call、apply、bind 的实现
记录 call、apply、bind 的模拟实现
call#
call()方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。MDN
note
注意:该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。
apply#
apply()方法调用一个具有给定 this 值的函数,以及以一个数组(或类数组对象)的形式提供的参数。MDN
note
注意:call() 方法的作用和 apply() 方法类似,区别就是 call() 方法接受的是参数列表,而 apply() 方法接受的是一个参数数组。
bind#
bind()方法创建一个新的函数,在bind()被调用时,这个新函数的 this 被指定为bind()的第一个参数,而其余参数将作为新函数的参数,供调用时使用。MDN
以下内容摘自 冴羽:JavaScript深入之bind的模拟实现
第一版#
第二版#
一个绑定函数也能使用 new 操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。
也就是说当 bind 返回的函数作为构造函数的时候,bind 时指定的 this 值会失效,但传入的参数依然生效。举个例子:
注意:尽管在全局和 foo 中都声明了 value 值,最后依然返回了 undefind,说明绑定的 this 失效了,结合 new 的原理可知此时 this 指向了 obj。
第三版#
避免修改 fBound.prototype 的时候,修改到绑定函数的 prototype,通过临时函数进行中转
总结#
当使用一个函数需要改变 this 指向的时候才会用到 call,apply,bind
如果传递的参数不多,则可以使用
fn.call(thisObj, arg1, arg2 ...)如果传递的参数很多,则可以用数组将参数整理好调用
fn.apply(thisObj, [arg1, arg2 ...])如果需要生成一个新的函数长期绑定某个函数给某个对象使用,则可以使用