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

180
07 марта 2019, 05:00

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

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

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

setTimeout(foo(), 10000);

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

el.onclick = foo();
el.addEventListener("click", foo());
createButton({
    name: "show alert",
    onClick: foo(),
});
Answer 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 или функцией обратного вызова).

Если вас волнует вопрос как в таком случае интерпретатор отличит функцию от переменной, то ответ на него - а ему и не нужно их отличать, имя функции - это разновидность имени переменной.

READ ALSO
Как остановить таймер на сервере nodejs?

Как остановить таймер на сервере nodejs?

перепробовал уже все методы, не могу остановить таймер на сервере nodejsПробовал разные варианты и с setInterval и setTimeout

145
Клик по элементу JS

Клик по элементу JS

Нужно написать скрипт, который при открытии страницы нажимает на тизер с рекламойСкелет:

168
Как сделать PopUp (модальное окно) чтобы оно срабатывало только по нажатию мыши?

Как сделать PopUp (модальное окно) чтобы оно срабатывало только по нажатию мыши?

Нашел в интернете как сделать модальное окноКод рабочий, но только есть один нюанс, модальное окно срабатывает когда пользователь заходит...

154