Перейти к содержанию

Выражения и объявление функций

Функции в JavaScript тоже являются объектами (шок, сенсация) — следовательно, их можно передавать и присваивать точно так же, как и любой другой объект. Одним из вариантов использования такой возможности является передача анонимной функции как функции обратного вызова в другую функцию — к примеру, для асинхронных вызовов.

Объявление function

// всё просто и привычно
function foo() {}

В следующем примере описанная функция резервируется перед запуском всего скрипта; за счёт этого она доступна в любом месте кода, вне зависимости от того, где она определена — даже если функция вызывается до её фактического объявления в коде.

foo() // сработает, т. к. функция будет создана до выполнения кода
function foo() {}

function как выражение

var foo = function () {}

В этом примере безымянная и анонимная функция присваивается переменной foo.

foo // 'undefined'
foo() // вызовет TypeError
var foo = function () {}

Так как в данном примере выражение var — это определение функции, переменная с именем foo будет заранее зарезервирована перед запуском скрипта (таким образом, foo уже будет определена во время его работы).

Но поскольку присвоения исполняются непосредственно во время работы кода, foo по умолчанию будет присвоено значение undefined (до обработки строки с определением функции):

var foo // переменная неявно резервируется
foo // 'undefined'
foo() // вызовет TypeError
foo = function () {}

Выражения с именованными фунциями

Существует еще нюанс, касающийся именованных функций создающихся через присваивание:

var foo = function bar() {
  bar() // работает
}
bar() // получим ReferenceError

Здесь объект bar не доступен во внешней области, так как имя bar используется только для присвоения переменной foo; однако bar можно вызвать внутри функции. Такое поведение связано с особенностью работы JavaScript с пространствами имен - имя функции всегда доступно в локальной области видимости самой функции.