0%

手动实现apply-call-bind

apply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Function.prototype.myApply = function(context,args){
// 如果是调用自己,则返回undefined
if(this===Function.prototype) return false;

context=context || window;

var fn = Symbol(),
result;

context[fn]=this;

if(Array.isarray(args)){
result = context[fn](...args);
}else{
result = context[fn]();
}

delete context[fn];
return result;
}

1.如果是调用自己,则返回undefined
2.判断context是否存在,不存在则调用window
3.新增一个Symbol属性,赋值给context
4.将当前函数赋值给这个属性
5.判断传参是否数组
6.如果是,则将其余的参数传入执行方法。如果否,则直接调用方法。
7.删除方法,返回。

call

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Function.prototype.myCall= function(context=window,...args){
if(this === Function.prototype) return undefined;

context= context || window

var fn = Symbol(),
result;

context[fn] = this;

result = context[fn](...args)
delete context[fn]
return result;
}

1.如果是调用自己,则返回undefined
2.判断context是否存在,不存在则调用window
3.新增一个Symbol属性,赋值给context
4.将当前函数赋值给这个属性
5.将其余的参数传入执行方法
6.删除方法,返回。

bind

1
2
3
4
5
6
7
8
9
10
11
12
Function.prototype.myBind = function(context=window,...args){
if(this === Function.prototype) return undefined;

const _this = this ;

return function F(...args2){
if(this instanceof F){
return new _this(...args,...args2)
}
_this.apply(context,args.concat(...args2))
}
}

1.处理参数,返回一个闭包
2.判断是否为构造函数调用,如果是则调用new调用当前函数
3.如果不是,则用apply,将contextargs参数传入

参考