Страницы

Поиск по вопросам

среда, 4 декабря 2019 г.

Как куда-нибудь передать функцию // почему событие вызывается сразу же?

#javascript #javascript_faq


Допустим, я написал функцию:

function foo() {
    alert("Hello, world!");
}


Почему когда я пытаюсь вызвать ее спустя некоторое время, она вместо этого вызывается
сразу же?

setTimeout(foo(), 10000);


И то же самое - с обработчиками событий? Пытался делать вот так:

el.onclick = foo();
el.addEventListener("click", foo());
createButton({
    name: "show alert",
    onClick: foo(),
});

    


Ответы

Ответ 1



Возможно, вы написали скобки около имени функции - foo() - случайно. А возможно, вы думаете что именно этими скобками функция отличается от переменной. В любом случае, ошибка скрыта именно тут. Кратко: уберите лишние скобки и все заработает. Javascript вычисляет выражения изнутри-наружу (как и многие другие языки). Очевидные примеры из математики: в выражении 2 + 2 * 2 сначала выполняется умножение, а потом - сложение, а в выражении (2 + 2) * 2 - наоборот. Когда вы пишите foo() - это оператор вызова функции. Это- такая же часть выражения как и любая математическая операция. И если где-то внутри выражения есть вызов foo() - то функция foo будет вызвана независимо от того что написано снаружи. Так, в примере setTimeout(foo(), 10000); сначала вызывается foo(), а потом результат вызова foo() (обычно это какой-нибудь undefined) передается в setTimeout: setTimeout(undefined, 10000). С точки зрения интерпретатора Javascript это не ошибка: он же не знает что такое foo, он просто послушно делает что вы ему сказали. Если вам не нужно вызывать функцию - то не надо ее вызывать. Просто убираем скобки около имени функции - и теперь она передается как есть, без вызова: setTimeout(foo, 10000); el.onclick = foo; el.addEventListener("click", foo); createButton({ name: "show alert", onClick: foo, }); Вызовут ее уже в другом месте, когда придет время. (Кстати, такая переданная куда-то функция обычно называется колбеком, callback или функцией обратного вызова). Если вас волнует вопрос как в таком случае интерпретатор отличит функцию от переменной, то ответ на него - а ему и не нужно их отличать, имя функции - это разновидность имени переменной.

Комментариев нет:

Отправить комментарий