JavaScript手写call,apply,bind
call,apply,bind,都能在JavaScript中改变this指向,那么如何用原生的JS来实现呢?
call
实现思路
参考call的语法规则,需要设置一个参数
thisArg
,也就是this的指向;将
thisArg
封装为一个Object;通过为
thisArg
创建一个临时方法,这样thisArg
就是调用该临时方法的对象了,会将该临时方法的this隐式指向到thisArg
上;执行
thisArg
的临时方法,并传递参数;删除临时方法,返回方法的执行结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30/*原生实现call*/
Function.prototype.mycall = function(thisArg, ...arr){
//先判断合不合法
if(thisArg === undefined || thisArg === null){
//指向全局window
thisArg = window;
}else{
//合法创建一个对象
thisArg = Object(thisArg);
}
//为thisArg创建一个临时方法
let specialMethod = Symbol('anything');
//这个this是保存的调用函数
thisArg[specialMethod] = this;
let result = thisArg[specialMethod](...arr);
//删除临时方法
delete thisArg[specialMethod];
//返回结果
return result;
}
test1 = {
str:'test1'
}
function test2() {
str = 'test2'
console.log(this.str);
}
test2()//test2
test2.mycall(test1)//test1
apply
- apply是第2个参数,这个参数是一个类数组对象:传给
func
参数都写在数组中
1 | Function.prototype.myapply = function(thisArg){ |
bind
实现思路
(1)拷贝调用函数:
- 调用函数,也即调用
myBind
的函数,用一个变量临时储存它; - 使用
Object.create
复制调用函数的prototype给funcForBind
;
(2)返回拷贝的函数funcForBind
;
(3)调用拷贝的函数funcForBind
:
new
调用判断:通过instanceof
判断函数是否通过new
调用,来决定绑定的context;- 通过
call
绑定this、传递参数; - 返回调用函数的执行结果。
1 | Function.prototype.mybind = function(objThis, ...params){ |