присвоение имени функции и добавление слушателей событий к ней приводит к «не определено» - PullRequest
0 голосов
/ 03 февраля 2019

Я все еще новичок в JavaScript, и у меня возникла следующая проблема.

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

Кратко о том, чего я пытаюсь достичь:

function game() {
// 
}

у меня проблема, когда я добавляю событие следующим образом:

for (let i = 0; i < cards.length; i++) {
    card = cards[i];
    card.addEventListener('click',  game);
}

Я получаю сообщение об ошибке с именованной функцией , которое говорит:

я не определен

Однако эта ошибка не возникает, когда я помещаю функцию как анонимную в параметре слушателя.

for (let i = 0; i < cards.length; i++) {
    card = cards[i];
    card.addEventListener('click', function game() {
      //
}

Объявление i глобально не былоне работает и не передает i в качестве параметра.

  • Полный код с анонимной функцией : Здесь
  • Полный код с именем Функция (что я хочу работать): Здесь

Ответы [ 3 ]

0 голосов
/ 03 февраля 2019

Ваша проблема в том, что ваша game функция не знает о i, потому что i не существует в вашей game функции из-за переменной области видимости.Чтобы это исправить, вы можете передать i в качестве аргумента в game следующим образом:

card.addEventListener('click', _ => game(i));

В приведенной выше строке вы вызываете функцию стрелки, которая затем вызывает функцию game.Это позволяет вам передавать аргумент в game.

И затем в вашем методе game принять переменную i в качестве аргумента:

function game(i) {

См. Рабочий пример здесь

0 голосов
/ 03 февраля 2019

Вы должны прочитать о lexical scoping в javascript, чтобы понять, почему i недоступна внутри именованной функции game

Внутри игровой функции, она может ссылаться только на переменные, которые находятся внутри лексической области видимости (или внутри this (это отдельная тема)

Проще говоря, вы можете передать «я» в игру, чтобы она заработала.Но так как addEventListener ожидает функцию, вы должны создать фабрику функций, которая использует немного closure

, отредактируйте вашу игру как

let game = (i) => () => {
  //existing game function 
}

, теперь используйте card.addEventListener('click', game(i));, и она должна работатькак и ожидалось

Вот рабочая скрипка для вашей справки: https://jsfiddle.net/uch1arny/2/

0 голосов
/ 03 февраля 2019

Чтобы получить доступ к различным i s, вам нужны разные замыкания, и, следовательно, вы получили разные ссылки на функции.Вы можете хранить их непосредственно на карте, чтобы потом их можно было удалить:

for (let i = 0; i < cards.length; i++) {
  const card = cards[i];
  card.addEventListener('click', card._click = function game() {
    //
  });
}

Затем вы можете удалить их позже с помощью:

card.removeEventListener("click", card._click);

То же самое также работаетесли вы переместите game снаружи и добавите параметр карри для i (может быть чище):

const game = i => () => {
  // ...
 };

for (let i = 0; i < cards.length; i++) {
  const card = cards[i];
  card.addEventListener('click', card._click = game(i));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...