Javascript 使用jQuery$(this)和ES6 Arrow函数(词法绑定)

Javascript 使用jQuery$(this)和ES6 Arrow函数(词法绑定),javascript,jquery,ecmascript-6,arrow-functions,Javascript,Jquery,Ecmascript 6,Arrow Functions,将ES6 arrow函数与词法结合使用,这种绑定非常好 但是,我刚才在使用典型的jQuery单击绑定时遇到了一个问题: class Game { foo() { self = this; this._pads.on('click', function() { if (self.go) { $(this).addClass('active'); } }); } } 改为使用箭头函数: class Game { foo() { this._p

将ES6 arrow函数与词法
结合使用,这种绑定非常好

但是,我刚才在使用典型的jQuery单击绑定时遇到了一个问题:

class Game {
  foo() {
    self = this;
    this._pads.on('click', function() {
      if (self.go) { $(this).addClass('active'); }
    });
  }
}
改为使用箭头函数:

class Game {
  foo() {
    this._pads.on('click', () => {
      if (this.go) { $(this).addClass('active'); }
    });
  }
}
然后将
$(this)
转换为ES5(self=this)类型的闭包


是一种让Traceur忽略词汇绑定的“$(this)”的方法吗?

这与Traceur无关,只是ES6的工作原理。这是您通过使用
=>
而不是
函数(){}
所要求的特定功能

如果您想编写ES6,您需要一直编写ES6,您不能在某些代码行上切换ES6,并且您绝对不能抑制或改变
=>
的工作方式。即使你可以,你也会得到一些只有你自己理解的奇怪的JavaScript版本,在你定制的Traceur之外,它永远不会正常工作,这绝对不是Traceur的重点

解决此特定问题的方法不是使用
this
来访问单击的元素,而是使用
事件。currentTarget

Class Game {
  foo(){
    this._pads.on('click', (event) => {
      if(this.go) {
        $(event.currentTarget).addClass('active');
      }
    });
  }
}
jQuery提供了
event.currentTarget
,这是因为,即使在ES6之前,jQuery也不可能总是将
应用于回调函数(即,如果它通过事件绑定绑定到另一个上下文)

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

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

你不能。这是箭头点函数的一半,它们关闭
这个
,而不是拥有自己的由调用方式设置的函数。对于问题中的用例,如果你想在调用处理程序时由jQuery设置
这个
,那么处理程序需要是一个
函数
函数

但是,如果您有使用箭头的理由(可能您想使用
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
      }
    });
  }
}
事件对象上的
currentTarget
与jQuery在调用处理程序时设置的
this
相同。

另一种情况 最高的答案是正确的,我投了赞成票

然而,还有另一种情况:

$('jquery-selector').each(() => {
    $(this).click();
})
可固定为:

$('jquery-selector').each((index, element) => {
    $(element).click();
})
这是jQuery中的一个历史错误,它将索引而不是元素作为第一个参数:

.每个(功能) 功能
类型:
函数(整数索引,元素)

为每个匹配元素执行的函数

参见:

正如他在回答同一问题时所说

因此,如果您使用ES6的arrow函数:
(event)=>{}
,那么您必须使用
$(event.currentTarget)
而不是
$(this)

您还可以使用更友好、更简洁的方式将currentTarget用作
({currentTarget})=>{}

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

最初,这个想法是@Meager在回答中提出的,我觉得它很有用,我想不是所有人都会读到这个评论,所以我把它写成了另一个答案。

注意,尽管它只对委托的
有分歧。
调用时,
这个
实际上是
事件。currentTarget
。这个答案行吗?像loganfs一样神话指出,
this
==
event.currentTarget
.No?@LéonPelletier No.
this
event.currentTarget
是相同的,除非
this
与ES6箭头函数一样绑定到封闭范围。如果您想保存一些代码,还可以对其进行解构:({currentTarget}=>{$(currentTarget).addClass('active')}这似乎是一个很好的例子,说明什么时候不使用arrow函数,因为
.on()
确实有一个
这个
值对您很有用。对我来说,
这个
引用事件目标比必须通过事件并手动查找目标要清楚得多。我没有太多使用箭头函数,但使用匿名函数来回似乎会让人困惑。fu也是如此像
$('jquery-selector').map这对我来说非常有用,可以在$('jquery-selector').filter之类的东西中使用。谢谢你说得这么清楚。查找
$jQueryElements.each()
?jquery实际上向每个对象发送一些参数,所以你根本不需要它=>它是
$(…)。每个((索引,el)=>console.log(el))
Class Game {
  foo(){
    this._pads.on('click', ({currentTarget}) => {
      if(this.go) {
        $(currentTarget).addClass('active');
      }
    });
  }
}