以下实现函数不会考虑过多的边界处理,只为实现功能
1.call实现
Function.prototype._call = function (thisArg, ...args) {
const exeFn = this;
const specialVariables = [undefined, null];
// 考虑传参不是对象形式的边界处理
thisArg = specialVariables.includes(thisArg) ? window : Object(thisArg);
// 防止thisArg属性名称的命名冲突
const key = Symbol("fn");
thisArg[key] = exeFn;
// 获取函数执行结果
const result = thisArg[key](...args);
delete thisArg[key];
return result;
};
2.apply实现
Function.prototype._apply = function (thisArg, argArray) {
const exeFn = this;
const specialVariables = [undefined, null];
// 考虑传参不是对象形式的边界处理
thisArg = specialVariables.includes(thisArg) ? window : Object(thisArg);
// 防止thisArg属性名称的命名冲突
const key = Symbol("fn");
thisArg[key] = exeFn;
argArray = argArray || [];
// 获取函数执行结果
const result = thisArg[key](...argArray);
delete thisArg[key];
return result;
};
3.bind实现
Function.prototype._bind = function (thisArg, ...argArray) {
return (...args) => {
const exeFn = this;
const specialVariables = [undefined, null];
// 考虑传参不是对象形式的边界处理
thisArg = specialVariables.includes(thisArg) ? window : Object(thisArg);
// 防止thisArg属性名称的命名冲突
const key = Symbol("fn");
thisArg[key] = exeFn;
// 获取函数执行结果
const result = thisArg[key](...[...argArray, ...args]);
delete thisArg[key];
return result;
};
};
4.测试代码
function foo(num1, num2, num3) {
console.log(this.name);
console.log(num1);
console.log(num2);
console.log(num3);
}
const obj = { name: "obj" };
foo._call(obj, 1, 2, 3); // obj 1 2 3
foo._apply(obj, [3, 4, 5]); // obj 3 4 5
const b = foo._bind(obj, 6, 7);
b(8); // obj 6 7 8