#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 или функцией обратного вызова). Если вас волнует вопрос как в таком случае интерпретатор отличит функцию от переменной, то ответ на него - а ему и не нужно их отличать, имя функции - это разновидность имени переменной.
Комментариев нет:
Отправить комментарий