总的规律:this 的绑定取决于调用位置!
1. 默认绑定(独立函数调用)。
function foo() {
console.log(this.a);
}
var a = 2;
foo(); // 2
2. 隐式绑定(调用位置有上下文对象,如例子中的 obj)
-》当函数引用有上下文对象时,隐式绑定规则会把函数调用中的 this 绑定到这个上下文对象。
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
}
obj.foo(); // 2
-》对象属性引用链中只有上一层或者最后一层在调用中起作用。
function foo() {
console.log(this.a);
}
var obj2 = {
a: 42,
foo: foo
}
var obj1 = {
a: 2,
obj2: obj2
}
obj1.obj2.foo(); // 42
-》隐式丢失
// example1-1
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
var bar = obj.foo;
var a = "oops, global";
bar(); // "oops, global",
/*
即使
var obj = {
a: 2,
foo: foo.bind(this)
};
var bar = obj.foo;
var a = "oops, global";
bar(); 输出也是"oops, global",
*/
// example1-2
function foo() {
console.log( this.a );
}
var a = 2;
var o = {
a: 3,
foo: foo
};
var p = {
a: 4
};
o.foo(); // 3
(p.foo = o.foo)(); // 2
example1-1中:bar 引用了foo函数本身,bar() 其实是一个不带任何修饰的函数调用,因此应用了默认绑定。
example1-2中:赋值表达式p.foo = o.foo 的返回值是目标函数的引用,因此调用位置是foo()而不是p.foo() 或者 o.foo(),所以使用默认绑定。
还有一种丢失的情况是调用参数回调函数。
function foo() {
console.log( this.a );
}
function doFoo(fn) {
fn(); // 调用位置
}
var obj = {
a: 2,
foo: foo
};
var a = "oops, global";
doFoo( obj.foo ); // "oops, global"