Допустим, я написал функцию:
function foo() {
alert("Hello, world!");
}
Почему когда я пытаюсь вызвать ее спустя некоторое время, она вместо этого вызывается сразу же?
setTimeout(foo(), 10000);
И то же самое - с обработчиками событий? Пытался делать вот так:
el.onclick = foo();
el.addEventListener("click", foo());
createButton({
name: "show alert",
onClick: foo(),
});
Ответ
Возможно, вы написали скобки около имени функции - 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 или функцией обратного вызова).
Если вас волнует вопрос как в таком случае интерпретатор отличит функцию от переменной, то ответ на него - а ему и не нужно их отличать, имя функции - это разновидность имени переменной.
Комментариев нет:
Отправить комментарий