removeEventListener - обратный вызов в самом определении функции? - PullRequest
2 голосов
/ 20 апреля 2020

У меня есть следующий код, в котором я добавляю прослушиватель событий в документ, а затем удаляю его.

document.addEventListener("keypress", gameStart);

function gameStart() {
    document.querySelector("h1").innerHTML = "Level 1";
    document.querySelector("h2").style.visibility = "hidden";
    document.removeEventListener("keypress", gameStart);
}

Я не могу обернуть голову, как у меня может быть обратный вызов gameStart в методе removeEventListener внутри определение самой gameStart (). Это кажется мне круговым, но я чувствую, что неправильно понимаю что-то здесь фундаментальное. Чего мне не хватает?

Ответы [ 4 ]

4 голосов
/ 29 апреля 2020

Все ответы довольно сложны. Немного проще:

1 - Вы не вызываете функцию gameStart на document.removeEventListener("keypress", gameStart); Вы фактически вызываете функцию removeEventListener() - Теперь прочитайте это снова, потому что я знаю, что это может сбить с толку.

2- Вы говорите функции removeEventListener(), чтобы удалить слушателя нажатия клавиш из функции gameStart(). gameStart никогда не вызывал себя в конце этой строки.

3- Пример из реальной жизни (вне вычислений):

Кто-то звонит вам на ваш телефон # xxx-xxx-xxxx, и вы берете трубку. и этот человек говорит вам сделать что-то (вы gameStart ()) после того, как вы закончите, вы хотите положить трубку, потому что вам больше нечего делать или обсуждать с другим человеком по телефону, поэтому вы говорите другому человеку, чтобы он положил трубку для вас, потому что в противном случае они будут постоянно слушать вызов по телефону (другой человек был слушателем события). Вы не повесили трубку, вы даже не участвовали в акции, чтобы повесить трубку, вы просто сказали им, что им нужно делать.

Надеюсь, это поможет!

4 голосов
/ 22 апреля 2020

В документации removeEventListener мы видим:

target.removeEventListener(type, listener[, options]);
target.removeEventListener(type, listener[, useCapture]);

...

слушатель
Функция обработчика событий EventListener для удаления из цели события.

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

4 голосов
/ 25 апреля 2020

Вы всегда можете передать ссылку на функцию, которую вы определяете, потому что

Функция не должна иметь все доступное во время определения, скорее это требование в то время вызова.

Это также фундаментально для рекурсии. например,

function getFactorial(num) {
    if (num <= 2) {
        return num;
    }
    return num * getFactorial(num - 1);
}

Возможно, следующее поможет вам понять больше:

function getType() {
    return typeof getType;
}

Выше функция всегда вернет "function".

Как насчет другой:

function getTypeOfX() {
    return typeof myObj.x;
}

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

Если вы попробуете это в консоли. Вы можете сделать

var myObj = {
    x: ""
}

даже после определения функции и снова вызвать getTypeOfX(), чтобы увидеть, что теперь она печатает "string".

Вывод: вот что упомянул @Quentin:

Variables used inside a function are not evaluated until the function is called.

4 голосов
/ 20 апреля 2020

Переменные, используемые внутри функции, не оцениваются до тех пор, пока функция не будет вызвана.

gameStart может, следовательно, ссылаться на себя, потому что она создана до того, как ее можно вызвать.

...