Использование jQuery $(this) с функциями ES6 Arrow (лексическая привязка)

Использование функций стрелок ES6 с лексической привязкой this отлично.

Тем не менее, я столкнулся с проблемой минуту назад, используя его с типичной привязкой кликов 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)" для лексической привязки?

69
задан JRodl3r 27 дек. '14 в 21:47
источник поделиться
4 ответов

Это не имеет ничего общего с 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 наложил this на функцию обратного вызова (т.е. если он привязан к другому контексту через bind.

120
ответ дан meagar 27 дек. '14 в 21:52
источник поделиться

Связывание событий

$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
});
32
ответ дан Ryan Huang 10 дек. '15 в 13:27
источник поделиться

Другой случай

Самый верный ответ правильный, и я его проголосовал.

Однако есть и другой случай:

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

Может быть исправлено как:

$('jquery-selector').each((index, element) => {
    $(element).click();
})
17
ответ дан Tyler Long 27 марта '17 в 16:54
источник поделиться

(Это ответ, который я написал для другой версии этого вопроса, прежде чем выучить, что это дубликат этого вопроса. Я думаю, что ответ довольно четко излагает эту информацию, поэтому я решил добавить его в качестве вики сообщества, хотя это в основном просто разные формулировки других ответов.)

Вы не можете. Эта половина точки стрелки функционирует, они закрываются над 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
ответ дан T.J. Crowder 30 нояб. '16 в 20:04
источник поделиться

Другие вопросы по меткам или Задайте вопрос