这是我参与「4月日新计划更文活动」的第25天。
今天跟大家聊一下call、apply和bind之间的区别。
call、apply和bind都是通过传入对象,动态改变this的指向的。
先通过几个例子来解释一下call和apply的区别。
apply和call
首先call和aplly的区别在于传递参数的方式不同。他们的第一个参数是动态传入改变this的对象。
而从第二个参数开始,就是传入到函数的具体参数。call方法是将参数一个一个的传入到函数中的;而apply方法是第二个参数作为数组,将所有的参数都传入到这个数组中,一次性全部传入到函数中。
例子一:
const obj1 = {
name: '小明'
}
const obj2 = {
name: '小方'
}
function fn(a, b) {
console.log(this.name);
return a + b;
}
const a1 = fn.call(obj1, 1, 2);
const a2 = fn.apply(obj2, [2, 4]);
console.log('a1>>>a2>>>', a1, a2);
上面这段代码输出的结果是:小明 小方 3 6
其实可以看到,在上述的call方法中传入了动态指向的对象obj1,这个时候fn函数的this就指向了obj1,所以此时打印的this.name,也就是obj1.name。
而call函数传入的参数,从第二个开始,就作为参数的起点,逐个传入。
而apply函数动态的传入了对象obj2,这个时候fn函数的this就指向了obj2,所以此时打印的this.name,也就是obj2.name。
第二个参数传入的是一个参数数组集合。
bind
bind与call和apply不同,它会返回一个新的函数,绑定了this指向。调用bind后,即使再次调用返回的函数,其this指向也不会改变。
看一个例子:
const obj1 = {
name: '小明'
}
function fn(a, b) {
console.log(this.name);
return a + b;
}
const foo = fn.bind(obj1, 1);
const b = foo(4)
console.log('b>>>>>', b);
上面的例子返回的结果是: 小明 5
可以看到执行了bind方法之后,传入了动态对象指向this,即obj1。那么此时this的指向就是obj1。
传入参数1,将参数的状态和this指向的状态都保存下来,返回给函数foo。
执行foo后,再传入第二个参数,与之前传入的第一个参数合并,参与计算,得到结果5。
根据上面的两个例子,我们可以做出call、apply和bind区别的总结。
总结
- call和apply可以改变函数内部this指向,并且立即执行函数
- call和apply的区别是参数的传递方式不同,一个是将参数逐个传入,一个是将所有参数都聚合成一个数组传入。
- bind可以改变函数内部this指向,但不会立即执行函数,会返回一个新的函数。
看到掘金上的好文章,如果对你有帮助,顺手点个赞,或者把文章收藏。不用担心找不到了,以后也能经常收到类似好回答,我会持续进行更新。