使用 jQuery $(this) 和 ES6 箭头函数(词法 this 绑定)

IT技术 javascript jquery ecmascript-6 arrow-functions
2021-02-06 07:53:08

使用带有词法this绑定的ES6 箭头函数很棒。

但是,我刚才在典型的 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)”的方法吗?

5个回答

这与 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 并不总是可以将 a 强加到this回调函数上(即,如果它通过bind.

如果你想保存一些代码,你也可以解构它: ({currentTarget}) => { $(currentTarget).addClass('active') }
2021-03-10 07:53:08
@LéonPelletier 编号thisevent.currentTarget除非this绑定到封闭范围,否则与 ES6 箭头函数相同。
2021-03-20 07:53:08
这个答案好吗?就像 loganfsmyth 指出的那样,this== event.currentTarget不?
2021-03-31 07:53:08
请注意,虽然它只对委托.on调用this有所不同,但实际上是event.currentTarget.
2021-04-02 07:53:08

事件绑定

$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))
2021-04-03 07:53:08

另一个案例

meagar 的回答是正确的,我已经投了赞成票。

然而,还有一种情况:

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

可以修复为:

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

这是 jQuery 中的一个历史错误,它把索引而不是元素作为第一个参数:

.each(函数)

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

见:https : //api.jquery.com/each/#each-function

相同的功能,如 $('jquery-selector').map
2021-03-17 07:53:08
这对我在 $('jquery-selector').filter 之类的东西中使用非常有用......感谢你把它说得如此清楚。
2021-03-20 07:53:08

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

你不能。这是箭头函数的一半,它们关闭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调用您的处理程序时。

正如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');
      }
    });
  }
}

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