Open nmsn opened 2 years ago
原文:https://juejin.cn/post/6844904116552990727
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 // 返回函数执行结果 }
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) // 执行当前函数(此处说明一下:虽然apply()接收的是一个数组,但在调用原函数时,依然要展开参数数组。可以对照原生apply(),原函数接收到展开的参数数组) delete thisArg[fn] // 删除我们声明的fn属性 return result // 返回函数执行结果 }
Function.prototype.myBind = function (obj, ...args) { var self = this // new优先级 var fbound = function () { self.apply(this instanceof self ? this : obj, args.concat(...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')() //输出写代码像蔡徐抻 ['a', 'b', 'c']
softbind 实现:https://github.com/shfshanyue/Daily-Question/issues/33#issuecomment-1237624135
bind 函数多次调用会已第一次绑定的 this 为准,softbind 已最后一次绑定传入的this为准;
call
apply
bind