首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript this 指向陷阱:賦值、逗號運算符、邏輯運算符導致方法丟失綁定

     編輯:程式設計綜合問答

現象代碼

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

核心規則:誰調用,this 就指向誰

  • 直接調用:obj.fn() → this = obj
  • 間接調用:賦值、逗號運算符、邏輯運算符(||、&&)返回函數引用 → 丟失綁定,默認綁定到全局對象(瀏覽器為 window,Node 為 global),嚴格模式下為 undefined。
  • 顯式綁定:call/apply/bind 強制指定 this。
  • 箭頭函數:無自身 this,捕獲外層詞法作用域的 this。

最佳實踐:避免意外丟失 this

  1. 使用箭頭函數定義方法(類屬性語法):
    class Foo {
        a = 40;
        bar = () => this.a; // this 永遠指向實例
    }
  2. 事件綁定時用 bind:
    btn.addEventListener('click', this.handler.bind(this));
  3. 回調傳遞前預綁定:
    setTimeout(() => this.method(), 1000);

總結

表達式 (foo.bar = foo.bar) 和 (foo.bar, foo.bar) 雖然看起來像在調用 foo.bar,實則只提取了函數引用,導致 this 綁定丟失。理解「調用位置」決定 this 是 JS 進階的必修課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved