对于JavaScript 开发者来说,this 的绑定一直是一件非常令人困惑的事。
this 是非常重要的,但是猜测、尝试并出错和盲目地从 Stack Overflow上复制和粘贴答案并不能让你真正理解 this 的机制。
首先得明白this既不指向函数自身也不指向函数的词法作用域,你也许被这样的解释误导过,但其实它们都是错误的。
this 实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。
// 默认绑定 => 在代码中,foo() 是直接使用不带任何修饰的函数引用进行调用的
// 函数调用时应用了 this 的默认绑定,因此 this 指向全局对象
function foo() {
console.log( this.a );
}
var a = 2;
foo(); // 2
// 隐式绑定
// 当 foo() 被调用时,它的落脚点确实指向 obj 对象
// 当函数引用有上下文对象时,隐式绑定规则会把函数调用中的 this 绑定到这个上下文对象
// 因为调用 foo() 时 this 被绑定到 obj,因此 this.a 和 obj.a 是一样的
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
//**隐式丢失**
// 虽然 bar 是 obj.foo 的一个引用,但是实际上,它引用的是 foo 函数本身,
// 因此此时的bar() 其实是一个不带任何修饰的函数调用,因此应用了默认绑定
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
var bar = obj.foo;
var a = "oops, global";
bar(); // oops, global
// 一种更微妙、更常见并且更出乎意料的情况发生在传入回调函数时:
function foo() {
console.log( this.a );
}
function doFoo(fn) {
// fn 其实引用的是 foo
fn(); // <-- 调用位置!
}
var obj = {
a: 2,
foo: foo
};
var a = "oops, global"; // a 是全局对象的属性
doFoo( obj.foo ); // "oops, global"
//参数传递其实就是一种隐式赋值,因此我们传入函数时也会被隐式赋值,所以结果和上一个例子一样
今天记录就到此结束,下次继续^_^