簡體   English   中英

使用 jQuery $(this) 和 ES6 箭頭函數(詞法 this 綁定)

[英]Using jQuery $(this) with ES6 Arrow Functions (lexical this binding)

使用帶有詞法this綁定的 ES6 箭頭函數非常棒。

但是,我剛才在使用典型的 jQuery 點擊綁定時遇到了一個問題:

class Game {
  foo() {
    self = this;
    this._pads.on('click', function() {
      if (self.go) { $(this).addClass('active'); }
    });
  }
}

使用箭頭 function 代替:

class Game {
  foo() {
    this._pads.on('click', () => {
      if (this.go) { $(this).addClass('active'); }
    });
  }
}

然后$(this)被轉換為 ES5 (self = this) 類型的閉包。

是一種讓 Traceur 忽略詞法綁定的“$(this)”的方法嗎?

這與 Traceur 和關閉某些東西無關,這就是 ES6 的工作原理。 這是您通過使用=>而不是function () { }來要求的特定功能。

如果你想寫 ES6,你需要一直寫 ES6,你不能在某些代碼行中切換進出它,你絕對不能抑制或改變=>的工作方式。 即使可以,您最終也會得到一些只有您自己理解的奇怪版本的 JavaScript,並且在您定制的 Traceur 之外永遠無法正常工作,這絕對不是 Traceur 的重點。

解決這個特定問題的方法不是使用this來訪問被點擊的元素,而是使用event.currentTarget

Class Game {
  foo(){
    this._pads.on('click', (event) => {
      if(this.go) {
        $(event.currentTarget).addClass('active');
      }
    });
  }
}

jQuery 專門提供event.currentTarget是因為,即使在 ES6 之前,jQuery 也不總是可以對回調 function 施加this (即,如果它通過bind綁定到另一個上下文。

事件綁定

$button.on('click', (e) => {
    var $this = $(e.currentTarget);
    // ... deal with $this
});

環形

Array.prototype.forEach.call($items, (el, index, obj) => {
    var $this = $(el);
    // ... deal with $this
});

另一個案例

meagar 的答案是正確的,我投了贊成票。

但是,還有另一種情況:

$('jquery-selector').each(() => {
    $(this).click();
})

可以固定為:

$('jquery-selector').each((index, element) => {
    $(element).click();
})

這是 jQuery 中的一個歷史錯誤,它將索引而不是元素作為第一個參數:

.每個(function)

function
類型: Function( Integer index, Element element )
為每個匹配的元素執行一個 function。

參見: https://api.jquery.com/each/#each-function

(這是我為這個問題的另一個版本寫的答案,在得知它是這個問題的副本之前。我認為答案相當清楚地匯總了信息,所以我決定將它添加為社區 wiki,盡管它在很大程度上只是不同其他答案的措辭。)

你不能。 這是箭頭函數的一半,它們關閉了this而不是擁有自己的,由它們的調用方式設置。 對於問題中的用例,如果您希望在調用處理程序時由this設置,則處理程序需要是function function。

但是如果你有使用箭頭的理由(也許你想用this來表示它在箭頭之外的含義),如果你願意,你可以使用e.currentTarget代替this

class Game {
  foo(){
    this._pads.on('click', e => {                   // Note the `e` argument
      if(this.go) {
        $(e.currentTarget).addClass('active');      // Using it
      }
    });
  }
}

事件 object 上的currentTarget與調用處理程序時 jQuery 設置this相同。

正如Meager在他對同一個問題的回答中所說,如果你想寫 ES6,你需要一直寫 ES6

所以如果你使用 ES6 的箭頭 function: (event)=>{} ,那么你必須使用$(event.currentTarget)而不是$(this)

您還可以使用更漂亮、更簡潔的方式將 currentTarget 用作({currentTarget})=>{}

Class Game {
  foo(){
    this._pads.on('click', ({currentTarget}) => {
      if(this.go) {
        $(currentTarget).addClass('active');
      }
    });
  }
}

最初, rizzi frank在 meagar 的回答中評論了這個想法,我覺得它很有用,我認為並非所有人都會閱讀該評論,所以我把它寫成另一個答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM