js 中的 call、apply、bind 笔记
apply call
Function.prototype.apply()、Function.prototype.call()
call() 和 apply() 是 Function 的方法,它的第一个参数是 this,第二个参数是是给 调用函数 传递的参数。call 和 apply() 都是为了改变某个函数运行时的 context 即上下文而存在的。
换句话说,就是为了改变函数体内部 this 的指向。
call() 需要把参数按顺序传递进去,而 apply() 则是 把参数放在数组里。他俩都是调用后立刻执行的
例如,有一个函数 fun 定义如下:
1 | window.color = "red"; |
其中
第一个参数 this 是你想指定的上下文,他可以任何一个 js 对象。
第二个参数是给 调用函数 传递的参数(如果调用函数没有参数就不传)。
如果 call() 方法没有参数,或者参数为 null 或 undefined,则等同于指向全局对象。另外箭头函数无法使用 call() apply() bind(),因为箭头函数中的 this 永远指向函数外最近的那个 this,因此不会起作用。
返回值:使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined。

有参数的情况下
1 | window.name = 'mark' |
JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数明确知道数量时,用call(),而不确定的时候,用apply(),然后把参数 push 进数组传递进去。
bind
Function.prototype.bind()
bind() 方法返回一个绑定了 this 的新函数(原函数的拷贝),在 bind() 被调用时,这个新函数的 this 被指定为bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
call() 和 apply() 它们两个是改变 this 的指向之后立即调用该函数,而 bind() 则不同,它是创建一个新函数,我们必须手动去调用它。
通俗讲就是通过bind() 方法,强制绑定了 this,绑定后的 this 不可改变
示例1:


示例2:
1 | const d = new Date(); |
上面代码中,我们将 d.getTime() 方法赋给变量 print,然后调用 print() 就报错了。这是因为 getTime() 方法内部的 this,绑定 Date 对象的实例,赋给变量 print 以后,内部的 this 已经不指向 Date 对象的实例了。
bind() 方法可以解决这个问题。
1 | const print = d.getTime.bind(d); |
上面代码中,bind() 方法将 getTime() 方法内部的 this 绑定到 d 对象,这时就可以安全地将这个方法赋值给其他变量了。
bind 方法的参数就是所要绑定 this 的对象,下面是一个更清晰的例子。
1 | const counter = { |
上面代码中,counter.inc 方法被赋值给变量 func。这时必须用 bind() 方法将 inc() 内部的 this 绑定到 counter,否则则会报错
this 绑定其他对象也是可以的
1 | const counter = { |
上面的代码中,bind() 方法将 inc() 内部的 this 绑定到 obj 对象。调用 func() 后,递增的就是 obj 内部的 count 属性。
bind()还可以接受更多的参数,将这些参数绑定原函数的参数。
1 | const add = function (x, y) { |
上面代码中,bind() 方法除了绑定 this 对象,还将 add() 函数的第一个参数 x 绑定成 5,然后返回一个新函数 newAdd(),这个函数只要再接受一个参数 y 就能运行了。