1.call
Function.prototype.mycall = function(thisArg,...args){
var fn = this;//这里的fn哪个函数调用就是哪个
thisArg = (thisArg !== null && thisArg !== undefined) ?Object(thisArg) : window;//第一个参数转为对象,转不成的改为window和原方法啊保持一致
thisArg.fn = fn;//添加属性
var result = thisArg.fn(...args);//正常用对象调用该对象内部方法的形式调用函数
delete thisArg.fn;//删除多余的属性
return result;
}
//测试
function foo() {
console.log("foo函数被执行", `this是${this}`)
}
foo.mycall('abc',1,3);
//实际上就是把第一个参数转为对象,把调用的函数foo作为对象的一个方法,对象调用
2.apply
//跟上面call一样,区别是传参用数组,用thisArg.fn(...argArray)
Function.prototype.myapply = function(thisArg,argArray){
var fn = this;
thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg): window;
thisArg.fn = fn;
var result;
if(!argArray){
result = thisArg.fn()
}else{
result = thisArg.fn(...argArray)
};
delete thisArg.fn;
return result;
}
//测试
function foo(){
console.log(`foo被执行,this是${this}`);
}
foo.myapply("abc",[1,2,3])
3.bind
Function.prototype.mybind = function(thisArg, ...argArray) {
// 1.获取到真实需要调用的函数
var fn = this
// 2.绑定this
thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg): window
function proxyFn(...args) {
// 3.将函数放到thisArg中进行调用
thisArg.fn = fn
// 特殊: 对两个传入的参数进行合并
var finalArgs = [...argArray, ...args]
var result = thisArg.fn(...finalArgs)
delete thisArg.fn
// 4.返回结果
return result
}
return proxyFn
}
//测试
function sum(num1, num2, num3, num4) {
console.log(num1, num2, num3, num4)
}
var newSum = sum.mybind("abc", 10, 20)
var result = newSum(30, 40)