Javascript 使用 jQuery $(this) 和 ES6 箭头函数(词法 this 绑定)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27670401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using jQuery $(this) with ES6 Arrow Functions (lexical this binding)
提问by JRodl3r
Using ES6 arrow functions with lexical thisbinding is great.
使用带有词法this绑定的ES6 箭头函数很棒。
However, I ran into an issue a moment ago using it with a typical jQuery click binding:
但是,我刚才在典型的 jQuery 单击绑定中使用它时遇到了一个问题:
class Game {
foo() {
self = this;
this._pads.on('click', function() {
if (self.go) { $(this).addClass('active'); }
});
}
}
Using an arrow function instead:
改用箭头函数:
class Game {
foo() {
this._pads.on('click', () => {
if (this.go) { $(this).addClass('active'); }
});
}
}
And then $(this)gets converted to ES5 (self = this) type closure.
然后$(this)转换为 ES5 (self = this) 类型的闭包。
Is a way to have Traceur ignore "$(this)" for lexical binding?
是一种让 Traceur 忽略词法绑定的“$(this)”的方法吗?
回答by meagar
This has nothing to do with Traceur and turning something off, this is simply how ES6 works. It's the specific functionality you're asking for by using =>instead of function () { }.
这与 Traceur 和关闭某些东西无关,这就是 ES6 的工作原理。这是您通过使用=>而不是function () { }.
If you want to write ES6, you need to write ES6 all the time, you can't switch in and out of it on certain lines of code, and you definitely cannot suppress or alter the way =>works. Even if you could, you would just wind up with some bizarre version of JavaScript that only you understand and which would never work correctly outside of your customized Traceur, which definitely isn't the point of Traceur.
如果你想写ES6,你需要一直写ES6,你不能在某些代码行上切换进出,绝对不能压制或改变=>工作方式。即使可以,您也会得到一些只有您理解的奇怪版本的 JavaScript,并且在您自定义的 Traceur 之外永远无法正常工作,这绝对不是 Traceur 的重点。
The way to solve this particular problem is not to use thisto gain access to the clicked element, but instead use event.currentTarget:
解决这个特殊问题的方法不是使用this来访问被点击的元素,而是使用event.currentTarget:
Class Game {
foo(){
this._pads.on('click', (event) => {
if(this.go) {
$(event.currentTarget).addClass('active');
}
});
}
}
jQuery provides event.currentTargetspecifically because, even before ES6, it is not always possible for jQuery to impose a thison the callback function (ie, if it was bound to another context via bind.
jQueryevent.currentTarget之所以特别提供是因为,即使在 ES6 之前,jQuery 也不总是可以this在回调函数上强加 a (即,如果它通过bind.
回答by Ryan Huang
Event binding
事件绑定
$button.on('click', (e) => {
var $this = $(e.currentTarget);
// ... deal with $this
});
Loop
环形
Array.prototype.forEach.call($items, (el, index, obj) => {
var $this = $(el);
// ... deal with $this
});
回答by Tyler Long
Another case
另一个案例
The top answer is correct and I've up-voted it.
最重要的答案是正确的,我已经投了赞成票。
However, there is another case:
然而,还有一种情况:
$('jquery-selector').each(() => {
$(this).click();
})
Could be fixed as:
可以修复为:
$('jquery-selector').each((index, element) => {
$(element).click();
})
This is a historical mistake in jQuery which puts the index, instead of the elementas the first argument:
这是 jQuery 中的一个历史错误,它把索引而不是元素作为第一个参数:
.each( function )
function
Type:Function( Integer index, Element element )
A function to execute for each matched element.
.each(函数)
函数
类型:Function( Integer index, Element element )
为每个匹配元素执行的函数。
回答by T.J. Crowder
(This is an answer I wrote for another version of this question, before learning it was a duplicate of this question. I think the answer pulls together the information fairly clearly so I decided to add it as a community wiki, although it's largely just different phrasing of the other answers.)
(这是我为这个问题的另一个版本写的答案,在了解到它是这个问题的副本之前。我认为答案相当清楚地将信息汇集在一起,所以我决定将其添加为社区维基,尽管它在很大程度上只是不同的其他答案的措辞。)
You can't. That's half the point of arrow functions, they close over thisinstead of having their own that's set by how they're called. For the use case in the question, if you want thisset by jQuery when calling the handler, the handler would need to be a functionfunction.
你不能。这是箭头函数的一半,它们关闭this而不是根据它们的调用方式设置自己的。对于问题中的用例,如果您想this在调用处理程序时由 jQuery 设置,则处理程序需要是一个function函数。
But if you have a reason for using an arrow (perhaps you want to use thisfor what it means outside the arrow), you can use e.currentTargetinstead of thisif you like:
但是,如果您有使用箭头的理由(也许您想使用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
}
});
}
}
The currentTargeton the event object is the same as what jQuery sets thisto when calling your handler.
该currentTarget事件对象是一样的什么jQuery的设置this调用您的处理程序时。
回答by Haritsinh Gohil
As Meagersaid in his answer on this same question If you want to write ES6, you need to write ES6 all the time,
正如Meager在他对同一个问题的回答中所说,如果你想写 ES6,你需要一直写 ES6,
so if you are using arrow function of ES6: (event)=>{}, then you have to use $(event.currentTarget)instead of $(this).
所以如果你使用 ES6: 的箭头函数(event)=>{},那么你必须使用$(event.currentTarget)代替$(this).
you can also use more nicer and cleaner way of using currentTarget as ({currentTarget})=>{},
您还可以使用更漂亮、更干净的方式使用 currentTarget as ({currentTarget})=>{},
Class Game {
foo(){
this._pads.on('click', ({currentTarget}) => {
if(this.go) {
$(currentTarget).addClass('active');
}
});
}
}
originally this idea was commented by rizzi frankin @Meager's answer, and i felt it useful and i think that not all people will read that comment so i have written it as this another answer.
最初这个想法是由rizzi frank在@Meager的回答中评论的,我觉得它很有用,我认为并不是所有人都会阅读该评论,所以我将其写为另一个答案。

