实现call方法
Function.prototype.myCall = function(thisArg, ...args) { const fn = Symbol(‘fn‘) // 声明一个独有的Symbol属性, 防止fn覆盖已有属性 thisArg = thisArg || window // 若没有传入this, 默认绑定window对象 thisArg[fn] = this // this指向调用call的对象,即我们要改变this指向的函数 const result = thisArg[fn](...args) // 执行当前函数 delete thisArg[fn] // 删除我们声明的fn属性 return result // 返回函数执行结果 } //测试 foo.myCall(obj)
实现一个apply,跟call相似,把参数列表改为参数数组
Function.prototype.myApply = function(thisArg, args) { const fn = Symbol(‘fn‘) // 声明一个独有的Symbol属性, 防止fn覆盖已有属性 thisArg = thisArg || window // 若没有传入this, 默认绑定window对象 thisArg[fn] = this // this指向调用call的对象,即我们要改变this指向的函数 const result = thisArg[fn](...args) // 执行当前函数 delete thisArg[fn] // 删除我们声明的fn属性 return result // 返回函数执行结果 } //测试 foo.myApply(obj, [])
实现bind,区别在于
Function.prototype.myBind = function (thisArg, ...args) { var self = this // new优先级 var fbound = function () { self.apply(this instanceof self ? this : thisArg, args.concat(Array.prototype.slice.call(arguments))) } // 继承原型上的属性和方法 fbound.prototype = Object.create(self.prototype); return fbound; } //测试 const obj = { name: ‘写代码像蔡徐抻‘ } function foo() { console.log(this.name) console.log(arguments) } foo.myBind(obj, ‘a‘, ‘b‘, ‘c‘)()