傻傻分不清之 apply(),call(),bind()
前言
JavaScript中的this往往是新人最难理解的,在多种情况下,this指向各种各种样,摸不着头脑,其实我们只要记住:“函数中使用的this,绑定的是运行时的对象,而不是定义时的对象”,就不会搞混乱,这次不是要讲this,而是要讲解改变this指向的apply(),call(),bind(),并且讲解他们的用法和区别。
作用
学习ES6以后千万不要认为this只有在class才会经常使用,我们要知道JavaScript里的函数也是对象。函数作为对象,有他的方法,包括强大的apply,call,bind这三个方法。一方面,apply和call几乎是相同的,它们被大量用来明确指定this的指向。我们也会在可变参数函数上使用apply。
bind
修正this指向
我们使用bind方法的主要目的是给this设置明确的值。换句话说就是,bind方法可以让我们决定在调用函数的时候将this绑定到哪个对象上。可能很多时候函数中并没有this,这个作用看起来相对的显得微不足道,但是,当你真的需要一个明确的对象来绑定函数的this值的时候,就显示出他的重要性了。
我们来举个例子,你就知道bind多有用了:
1 | <body> |
点击后,啥都不输出,因为user.sayName是被button调用的,此刻this指向的是button,不信不可以改为console.log(this),控制台中打印的是button这个元素本身,这时候,我们就能用bind改变this的指向,如下:
1 | var button = document.getElementById('button1') |
这个时候,就能输出user对象里面的name啦~
借用方法
1 | var user = { |
我们通过bind,将user中的方法借用到adnmn中,但是这样会存在一个问题,我们在隐形中为admin对象添加了一个新的方法,但是我们并不想在借用方法的时候这样做,因为admin对象上可能已经有了一个名为sayName的方法或者属性了。我们不想因为巧合而把原来的方法给重写了。所以,我们会在下面讨论call和apply,最好是使用它们二者之一来借用方法。
apply
其实apply起到的作用和bind或者call一样,都是来改变this的指向,我们先来看看apply的用法:
1 | var user = { |
这里我们注意到,admin通过apply将user的方法借用,这里我们要注意,这里的借用,是真正的借用,admin并不会复制一个setFullName函数到自己身上,我们从他们之间的写法也能看出来:
- bind:
1 | admin.sayName = user.sayName.bind(admin) //复制 |
- apply:
1 | user.setFullName.apply(admin,['middle', 'BE']) //直接调用 |
这说明apply并没有复制函数到本身上,而是通过直接调用,这也有助于我们分清两者直接的写法差异,和原理是的区别。
call
我们同样用上面的例子,用call来实现一遍,以便我们认清之间的差异:
1 | var user = { |
细心一点便能发现,两者之间的区别只是添加参数的方式不一样,call是将参数分开来放入函数中,而apply是将参数喝合在一个数组中放入。
总结
这里我们简单提了bind、apply、call的简单用法以及他们的区别,bind一般用来修正事件触发时this的指向,而apply和call一般是用来借用方法,以及他们为什么会设置两种不同的参数传入方式,以及他们更深入的使用,且听我下回分享~