1. call方法的实现是通过this指针的指向不同实现的。
Function.prototype.myCall = function (arg) { let context = arg || window; // 如果this为空则指向window context.fn = this; // 当前this指向调用的方法 const args = [...arguments].slice(1); const result = context.fn(...args); delete context.fn; return result; } function test(res) { console.log(res, ">>>>>>>>>>>") } test.myCall(this, 123, 223)
2. apply方法的实现,apply方法可以借助call方法进行实现,也可以单独进行实现,apply方法第二个参数传入的是一个数组,这也是和call的区别
Function.prototype.myApply = function (context, arr) { this.call(context, ...arr); } // 借助call方法进行实现 Function.prototype.myApply = function (arg, arr) { let context = arg || window; context.fn = this; let result = context.fn(...arr); delete context.fn; return result; } test.myApply(this, [123, 223])
3. bind方法的实现,bind方法的话和上边两个方法有区别的是,bind方法不是立即执行的,也就是说不能返回执行结果,应该返回的是一个函数。
Function.prototype.myBind = function (_this, ...args1) { return (...args2) => { this.apply(_this, [...args1, ...args2]) } } // 这种是利用apply或者自己写的myApply方法 Function.prototype.myBind = function (_this, ...args1) { return (...args2) => { let context = _this || window; context.fn = this; const result = context.fn(...args1.concat(...args2)); delete context.fn; return result; } } // 这种是利用es6方法进行封装的