var a = 20;
var foo = {
a: 40,
bar: function () {
var a = 10;
return this.a;
}
};
console.log(
foo.bar(), // 40
(foo.bar)(), // 40
(foo.bar = foo.bar)(), // 20
(foo.bar, foo.bar)(), // 20
(foo.bar.apply(window)), // 20
(foo.bar.apply(foo)) // 40
);
| 表達式 | 結果 | 原因 |
|---|---|---|
foo.bar() |
40 | 方法調用模式,this 指向 foo |
(foo.bar)() |
40 | 分組運算符不改變引用,仍是方法調用 |
(foo.bar = foo.bar)() |
20 | 賦值表達式返回函數對象本身,非方法調用 → this 指向全局 window (非嚴格模式) |
(foo.bar, foo.bar)() |
20 | 逗號運算符返回最後一個表達式的值(函數對象),同理丟失綁定 |
foo.bar.apply(window) |
20 | 顯式綁定 this = window,window.a = 20 |
foo.bar.apply(foo) |
40 | 顯式綁定 this = foo,foo.a = 40 |
obj.fn() → this = obj||、&&)返回函數引用 → 丟失綁定,默認綁定到全局對象(瀏覽器為 window,Node 為 global),嚴格模式下為 undefined。call/apply/bind 強制指定 this。this,捕獲外層詞法作用域的 this。class Foo {
a = 40;
bar = () => this.a; // this 永遠指向實例
}btn.addEventListener('click', this.handler.bind(this));setTimeout(() => this.method(), 1000);表達式 (foo.bar = foo.bar) 和 (foo.bar, foo.bar) 雖然看起來像在調用 foo.bar,實則只提取了函數引用,導致 this 綁定丟失。理解「調用位置」決定 this 是 JS 進階的必修課。