将jQuery $(this)与ES6箭头函数一起使用(词汇表this绑定)


128

将ES6箭头功能与词汇this绑定一起使用非常好。

但是,我刚才遇到一个问题,将它与典型的jQuery click绑定一起使用:

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)”?


这似乎是何时不使用箭头功能的完美示例,因为.on()确实具有this对您有用的值。对我来说,this引用事件目标比必须通过事件并手动找到目标要清晰得多。我在箭头功能上玩的还不多,但是使用匿名功能来回移动似乎很混乱。
robisrob

Answers:


194

这与Traceur和关闭某些功能无关,这只是ES6的工作方式。这是您要使用=>而不是要求的特定功能function () { }

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

解决此特定问题的方法不是使用this来获得对clicked元素的访问,而是使用event.currentTarget

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

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


4
请注意,尽管它仅对委托.on呼叫this有所不同,但实际上是event.currentTarget
loganfsmyth 2014年

这个答案可以吗?就像loganfsmyth指出的那样,this== event.currentTarget。没有?
莱昂佩尔蒂埃

3
@LéonPelletier号thisevent.currentTarget除非this绑定到封闭范围,否则与ES6箭头功能相同。
meagar

8
如果您想保存一些代码,也可以对其进行解构:({currentTarget})=> {$(currentTarget).addClass('active')}
Frank

55

事件绑定

$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
});

寻找$jQueryElements.each()?jQuery实际上向每个对象发送了一些参数,因此您根本不需要它=>$(...).each((index, el) => console.log(el))
jave.web

53

另一种情况

最重要的答案是正确的,我已经投票赞成。

但是,还有另一种情况:

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

可以固定为:

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

这是jQuery中的一个历史错误,该错误将index而不是element作为第一个参数:

.each(函数)

函数
类型:Function( Integer index, Element element )
为每个匹配的元素执行的函数。

请参阅:https//api.jquery.com/each/#each-function


1
同样像类函数$('jquery-selector').map
尼古拉斯Siegmundt

这对我在$('jquery-selector')。filter等中使用非常有用...感谢您说得这么清楚。
R琼斯

8

(这是我为该问题的另一个版本写的答案,在得知它是该问题的重复版本之前。我认为该答案将信息清楚地归纳在一起,因此我决定将其添加为社区Wiki,尽管两者之间有很大的不同其他答案的措词。)

你不能 这只是箭头函数的一半,它们关闭了,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
      }
    });
  }
}

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


5

正如Meager在回答相同问题时所说的那样,如果您想编写ES6,则需要一直编写ES6

因此,如果您使用的是ES6:的箭头功能(event)=>{},则必须使用$(event.currentTarget)代替$(this)

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

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

最初,这个想法是由rizzi frank@Meager的答案中评论的,我觉得它很有用,我认为并非所有人都会读到该评论,所以我将其写为另一个答案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.