call、apply、 bind 通常用于修改this的指向,文章简述它们的区别以及实现原理
区别
call 接受多个参数
apply 只接受一个数组参数
bind 接受多个参数, 与 call 和 apply 不同, bind不执行宿主函数
使用 func.call (thisArg, param1, param2, ...) func.apply (thisArg, [param1,param2,...]) func.bind (thisArg, param1, param2, ...) let a = {test : 1 }Array .prototype .push .call (a,{test2 :2 })a const a = = [].slice .call (arguemnt)
call 实现 Function .prototype .myCall = function (context, ...args ) { context = context || window context.fn = this const res = context.fn (...args) delete context.fn return res }
apply实现 实现差不多,主要在于参数
Function .prototype .myBind = function (context, ...args ) { context = context || window context.fn = this const res = context.fn (args) delete context.fn return res }
bind 实现 bind 实现相对复杂一些,主要是因为 bind返回的函数可以当作构造函数
Function .prototype .myBind = function (context, ..args ) { const self = this return function (..args2 ) { return self.apply (context, [...args,...args2]) } }
如果作为构造函数, 那么 new 的时候, this的优先级是最高的,bind的this就失效了
new的过程(不考虑显式返回的情况): 1、 创建一个空的对象 2、 将this指向当前对象, 对象的原型也会 发生改变 3、 执行构造函数内部代码 4、返回对象
因此,关键在于判断 this 的指向问题
最终版实现
Function .prototype .myBind = function (context, ...args ) { if (typeof this !== 'function' ) { throw new Error ("Function.prototype.bind - what is trying to be bound is not callable" ) } const self = this const fNOP = function ( ) {} const fBound = function (..args2 ) { return self.apply ( this instanceof fNOP ? this : context,[...args,...args2]) } fNOP.prototype = this .prototype fBound.prototype = new fNOP () return fBound; }