通过js模拟实现,不过度考虑边界情况
call的实现
Function.prototype.myCall = function (thisArg, ...argArray) {
// 1.thisArg转换对象类型和默认值处理
thisArg =
thisArg !== null && thisArg !== undefined ? Object(thisArg) : window;
// 2.拿到执行函数添加到this对象上
thisArg.fn = this;
// 3.执行函数(this通过隐式绑定)
var res = thisArg.fn(...argArray);
// 删除添加的属性
delete thisArg.fn;
// 4.返回结果
return res;
};
function sum(num1, num2) {
console.log(this, num1, num2);
return num1 + num2;
}
var res = sum.call('call', 1, 2); // [String: 'call'] 1 2
var res1 = sum.myCall('myCall', 1, 2); // [String: 'myCall'] { fn: [Function: sum] } 1 2
apply的实现
apply和call主要在参数区别
Function.prototype.myApply = function (thisArg, argArray) {
// 1.thisArg转换对象类型和默认值处理
thisArg =
thisArg !== null && thisArg !== undefined ? Object(thisArg) : window;
// 2.拿到执行函数添加到this对象上
thisArg.fn = this;
// 3.执行函数(this通过隐式绑定)
if (Array.isArray(argArray)) {
var res = thisArg.fn(...argArray);
} else {
var res = thisArg.fn();
}
// 删除添加的属性
delete thisArg.fn;
// 4.返回结果
return res;
};
function sum(num1, num2) {
console.log(this, num1, num2);
return num1 + num2;
}
var res = sum.apply('apply', [1, 2]); // [String: 'apply'] 1 2
var res1 = sum.myApply('myApply', [1, 2]); // [String: 'myApply'] { fn: [Function: sum] } 1 2
bind的实现
Function.prototype.myBind = function (thisArg, ...argArray) {
// 1.thisArg转换对象类型和默认值处理
thisArg =
thisArg !== null && thisArg !== undefined ? Object(thisArg) : window;
// 2.拿到执行函数添加到this对象上
thisArg.fn = this;
// 3.返回绑定好this的待执行函数
return function (...args) {
// 4.执行函数,并拼接所有参数(this通过隐式绑定)
var res = thisArg.fn(...argArray.concat(args));
// 删除添加的属性
delete thisArg.fn;
// 5.返回结果
return res;
};
};
function sum(num1, num2, num3) {
console.log(this, num1, num2, num3);
return num1 + num2 + num3;
}
var newSum = sum.bind('bind', 1, 2);
var res = newSum(3); // [String: 'bind'] 1 2 3
var newSum1 = sum.myBind('myBind', 1, 2);
var res1 = newSum1(3); // [String: 'myBind'] { fn: [Function: sum] } 1 2 3