对于JavaScript 开发者来讲,this 的绑定一直是一件很是使人困惑的事。函数
this 是很是重要的,可是猜想、尝试并出错和盲目地从 Stack Overflow上复制和粘贴答案并不能让你真正理解 this 的机制。oop
首先得明白this既不指向函数自身也不指向函数的词法做用域,你也许被这样的解释误导过,但其实它们都是错误的。ui
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"
//参数传递其实就是一种隐式赋值,所以咱们传入函数时也会被隐式赋值,因此结果和上一个例子同样
复制代码
今天记录就到此结束,下次继续^_^spa