call 的 polyfill
Function.prototype.call = function(obj){ // 判断甲方是不是一个函数,不是函数抛出错误 if(typeof this !== 'function'){ throw new Error('当前调用 call 方法的不是函数!'); } // 保存甲方给的参数 const args = [...arguments].slice(1); // 确定乙方的类型,因为可以传 null 和 undefined obj = obj || window; // 将甲方的内容保存为乙方的一个属性,为了保证不与乙方的 key 键名重复 const fn = Symbol('fn'); obj[fn] = this; const result = obj[fn](...args); delete obj[fn]; return result; }
apply 的 polyfill
Function.prototype.apply = function(obj){ if(typeof this !== 'function'){ throw new Error('当前调用 apply 方法的不是函数!'); } // 此处与 call 有区别 const args = arguments[1]; obj = obj || window; const fn = Symbol('fn'); obj[fn] = this; const result = obj[fn](...args); delete thisArgs[fn]; return result; }
bind 的 polyfill
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被 bind 的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。
// obj 为要绑定的对象 Function.prototype.bind = function(obj, ...args){ if(typeof this !== 'function'){ throw new Error('当前调用 bind 的不是函数'); } // 保存甲方的参数 var bindArgs = args; var self = this; var fBound = function(...args){ return self.apply(this instanceof fBound? this: obj, bindArgs.concat(args)); } Object.setPrototypeOf(fBound, self.prototype); return fBound; }