this的全面解析
一、this的四条绑定规则
1、默认绑定
适用于独立函数调用,当无法应用其他规则时就适用的是默认规则。
2、隐式绑定
需要考虑的规则时调用位置是否有上下文对象,或者说是否被某个对象拥有或者包含。1
2
3
4
5
6
7
8function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
}
obj.foo();
3、显式绑定
通常使用call(…)和apply(…)进行显式绑定。1
2
3
4
5
6
7function foo() {
console.log(this.a);
}
var obj= {
a:2
};
foo.call(obj)
- 硬绑定bind的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18function foo(something) {
console.log(this.a, something);
return this.a + something;
}
// 简单的辅助绑定函数
function bind(fn, obj) {
return function () {
return fn.apply(obj, arguments)
}
}
var obj = {
a: 2
}
var bar = bind(foo, obj);
var b = bar(3);
console.log(b)
4、new绑定
1 | function foo(a) { |
使用new来调用foo(…)时,我们会构造一个新对象并把它绑定到foo(…)调用中的this上。new是最后一种可以影响函数调用时this绑定行为的方法,我们称之为new绑定。
二、四条绑定规则的优先级
显示绑定–>new绑定–>隐式绑定–>默认绑定
- 判断this的方法
函数是否在new中调用,如果是的话this绑定的是新创建的对象。
1
var bar = new foo()
函数是否通过call、apply(显式绑定)或者硬绑定调用,如果是的话,this绑定的是指定的对象。
1
var bar = foo.call(obj2)
函数是否在某个上下文对象中调用(隐式调用),如果是的话,this绑定的是哪个上下文对象。
1
var bar = obj1.foo()
4.如果都不是的话,使用的是默认绑定
注:箭头函数不会使用四条标准的绑定规则,而是根据当前的词法作用域来决定this。