call、apply和bind之间的区别是什么?

163 阅读2分钟

这是我参与「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指向,但不会立即执行函数,会返回一个新的函数。

看到掘金上的好文章,如果对你有帮助,顺手点个赞,或者把文章收藏。不用担心找不到了,以后也能经常收到类似好回答,我会持续进行更新。