Использование 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)" для лексической привязки?

45
задан 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.

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

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

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

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

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

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

$('jquery-selector').each((index, element) => {
    $(element).click();
})
7
ответ дан 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 при вызове обработчика.

4
ответ дан T.J. Crowder 30 нояб. '16 в 20:04
источник поделиться

Другие вопросы по меткам