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;
} 
京公网安备 11010502036488号