ES6の矢印関数でjQuery $(this)を使用する(字句thisバインディング)


127

字句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)」を無視させる方法はありますか?


これ.on()は実際にthis有用な値を持っているので、アロー関数を使用しない場合の完璧な例のようです。私thisには、イベントを渡して手動でターゲットを見つける必要があるよりも、イベントターゲットを参照する方がはるかに明確です。私はアロー関数をあまり使っていませんが、無名関数を行ったり来たりするのは混乱するようです。
robisrob

回答:


193

これはTraceurとは関係がなく、何かをオフにすることとは関係ありません。これは単にES6が機能する方法です。それはあなたが=>代わりに使用することによって求めている特定の機能ですfunction () { }

ES6を作成する場合は、常にES6を作成する必要があり、特定のコード行でES6を切り替えたり、切り替えたりすることはできません=>。また、動作を抑制または変更することはできません。たとえできたとしても、あなただけが理解していて、カスタマイズされたTraceurの外では正しく機能しない、奇妙なバージョンのJavaScriptを試してみるだけです。これは間違いなくTraceurのポイントではありません。

この特定の問題を解決する方法はthis、クリックされた要素へのアクセスを得るために使用するのではなく、代わりに以下を使用することevent.currentTargetです:

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

event.currentTarget特にjQueryが提供するのは、ES6より前でも、jQueryがthisコールバック関数にを強制することが常に可能であるとは限らないためです(つまり、jQueryがを介して別のコンテキストにバインドされている場合)bind


4
委任された.on呼び出しに対してのみ分岐しますが、this実際にはであることに注意してくださいevent.currentTarget
loganfsmyth 2014

この回答でよろしいですか?前述のloganfsmythと同様に、this== event.currentTargetです。番号?
レオン・ペルティエ

3
LéonPelletier号@ thisevent.currentTargetしない限り、同じであるthisES6矢印関数と同様に、封入スコープに結合されています。
貧弱

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の歴史的な間違いです。

.each(関数)

function
型:Function( Integer index, Element element )
一致した各要素に対して実行する関数。

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


1
同様の機能$('jquery-selector').map
Nicholas 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イベントオブジェクトのonは、jQueryがthisハンドラーを呼び出すときに設定するものと同じです。


5

厳しい局面では、この同じ質問に彼の答えで述べてあなたがES6を書きたい場合は、あなたがES6のすべての時間を記述する必要があり

ES6:のアロー機能(event)=>{}を使用している場合は、の$(event.currentTarget)代わりに使用する必要があり$(this)ます。

また({currentTarget})=>{}、currentTargetをとして使用する、より洗練された方法を使用できます 。

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

もともとこのアイデアは@Meagerの回答でrizzi frankによってコメントされました

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.