Это поведение JavaScript называется Подъемник. Существует хорошее объяснение на MDN (https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)
В JavaScript возведены функции и переменные. Подъем - это поведение JavaScript для перемещения объявлений в верхней части области (глобальная область видимости или область текущей функции).
Это означает, что вы можете использовать функцию или переменную до того, как она была объявлена, или другими словами: функция или переменная могут быть объявлены после того, как они уже были использованы.
В принципе, если вы объявляете переменную как это:
console.log(s); // s === undefined
var s = 'some string';
s
декларация будет «водрузил» к началу объема (т.е. там не будет никаких ReferenceError
на линии с console.log
). Значение переменной в этот момент не будет определено, хотя.
То же самое происходит с назначением анонимной функции переменным, так:
console.log(f); // f === undefined
f(); // TypeError: f is not a function
var f = function() {}; // assigning an anonymous function as a value
f(); // ok, now it is a function ;)
переменными будет развеваться и, таким образом, видны во всем объеме, но это значение, даже если это функция, будет все еще не определено - отсюда ошибка, если вы попытаетесь выполнить его.
С другой стороны, если вы объявляете с именем функции:
console.log(f); // f === function f()
f(); // we can already run it
function f() {}; // named function declaration
Это определение также будет поднят, так что вы можете запустить его даже в первой строке рамки вы объявили его.
Возможный дубликат функции [Javascript function scoping and hoisting] (http://stackoverflow.com/questions/7506844/javascript-function-scoping-and-hoisting) – DTing
Да. При вводе контекста [* execute *] (http://ecma-international.org/ecma-262/6.0/index.html#sec-execution-contexts) все объявления функций и переменных обрабатываются до запуска любого кода. – RobG