this的绑定规则:
1 默认绑定
请思考一下以下代码:
function foo(){
console.log(this.a)
}
var a= 2
foo()
代码的结果输出2,因为this绑定的是全局对象。
2隐式绑定
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo };
obj.foo(); // 2
输出结果之所以是2是因为foo()被当作引用属性添加到了obj中,当foo作为属性被调用的时候this会被绑定到obj上。同时,对象属性引用链中只有最顶层或者说最后一层会影响调用位置。如:
function foo() {
console.log( this.a );
}
var obj2 = { a: 42,
foo: foo
};
var obj1 = {
a: 2,
obj2: obj2
};
obj1.obj2.foo(); // 42
3 显式绑定
显式绑定主要通过call,apply,bind来实现。那我们先大概了解一下三者的区
别:
bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用
call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。
回归主题,思考如下代码:
function foo() {
console.log( this.a );
}
var obj = { a:2
};
foo.call( obj ); // 2
通过foo.call(obj)我们将this绑定到了obj上并成功调用到了obj的属性a。
4 new绑定
new来构造函数的时候做了四件事:
- 建立一个新的对象
- 将函数原型连接到新对象原型
- 将新对象的this绑定到函数调用的this上
- 如果函数没有返回就返回新函数
function foo(a) {
this.a = a;
}
var bar = new foo(2);
console.log( bar.a ); // 2
优先级:
new绑定
|
显式绑定
|
隐式绑定
|
默认绑定
小结:
到这我觉得已经够用了。在《你不知道的js》中还有很多其他关于this的,但我觉得就目前而言对我已经差不多了。再往下去深究的意义不大。(如果后面觉得有必要也会回头重新研究)