Подтвердить что ты не робот

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

4b9b3361

Ответ 1

Это не имеет ничего общего с 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.

Ответ 2

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

$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
});

Ответ 3

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

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

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

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

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

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

Ответ 4

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

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

Как сказал Скудный в своем ответе на этот же вопрос . Если вы хотите писать ES6, вам нужно все время писать ES6,

так что если вы используете функцию стрелки ES6: (event)=>{}, то вам нужно использовать $(event.currentTarget) вместо $(this).

Вы также можете использовать более приятный и чистый способ использования currentTarget как ({currentTarget})=>{},

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

Первоначально эта идея была прокомментирована rizzi frank в ответе @Meager, и я чувствовал, что это полезно, и я думаю, что не все люди прочтут этот комментарий, поэтому я написал его как этот другой ответ.