使用jQuery $(this)和ES6 Arrow函数(词汇这个绑定)

JRo*_*l3r 103 javascript jquery ecmascript-6 arrow-functions

使用带有词法this绑定的ES6箭头功能非常棒.

但是,我刚刚遇到一个问题,使用它与典型的jQuery点击绑定:

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

改为使用箭头功能:

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

然后$(this)转换为ES5(self = this)类型闭包.

是一种让Traceur忽略"$(this)"进行词法绑定的方法吗?

mea*_*gar 168

这与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');
      }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

jQuery event.currentTarget特别提供,因为即使在ES6之前,jQuery也不总是可以强加一个this回调函数(即,如果它通过它绑定到另一个上下文)bind.

  • 如果你想保存一些代码,你也可以解构它:({currentTarget})=> {$(currentTarget).addClass('active')} (6认同)
  • Note, though it only diverges for delegated `.on` calls, `this` is actually `event.currentTarget`. (3认同)
  • *“如果你想写 ES6,你就需要一直写 ES6。”* 这是一个非常可疑的说法。ES2015+ 完全向后兼容*(除了**非常**少数**非常**边缘情况)*。您可以混合“class X”并分配给“X.prototype”上的内容,以选择一个随机示例。您可以继续使用“var”(尽管我不会),或者使用“var x = this;”代替箭头函数(尽管我不会)。等等。你*不能*做的是同时使用`this`来做两个不同的事情。:-) (3认同)
  • @LéonPelletierNo.`his`和`event.currentTarget`是相同的,除非`this`绑定到封闭范围,就像ES6箭头函数一样. (2认同)

Rya*_*ang 44

事件绑定

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

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


Tyl*_*ong 34

另一个案例

最佳答案是正确的,我已经投票了.

但是,还有另一种情况:

$('jquery-selector').each(() => {
    $(this).click();
})
Run Code Online (Sandbox Code Playgroud)

可以修复为:

$('jquery-selector').each((index, element) => {
    $(element).click();
})
Run Code Online (Sandbox Code Playgroud)


Har*_*hil 8

正如Meager在他对同一个问题的回答中所说,如果你想写 ES6,你需要一直写 ES6

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

您还可以使用更漂亮、更干净的方式使用 currentTarget as ({currentTarget})=>{}

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

最初,这个想法是由rizzi frank在 meagar 的回答中评论的,我觉得它很有用,而且我认为并非所有人都会阅读该评论,因此我将其写为另一个答案。


T.J*_*der 6

(这是我为这个问题的另一个版本写的答案,在学习之前它是这个问题的重复.我认为答案相当清楚地汇总了信息所以我决定将它添加为社区维基,尽管它在很大程度上是不同的其他答案的措辞.)

你不能.这是箭头函数的一半,它们关闭this而不是根据它们的调用来设置它们自己.对于问题中的用例,如果你想this在调用处理程序时由jQuery设置,那么处理程序将需要是一个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
      }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

currentTarget事件对象是一样的什么jQuery的设置this调用您的处理程序时.