tl; dr. Если вы ничего не звоните, пока все не загрузится, все будет в порядке.
Изменить: для обзора, который также охватывает некоторые объявления ES6 (let
, const
): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet
Это странное поведение зависит от
- Как вы определяете функции и
- Когда вы им звоните.
Вот несколько примеров.
bar(); //This won't throw an error
function bar() {}
foo(); //This will throw an error
var foo = function() {}
bar();
function bar() {
foo(); //This will throw an error
}
var foo = function() {}
bar();
function bar() {
foo(); //This _won't_ throw an error
}
function foo() {}
function bar() {
foo(); //no error
}
var foo = function() {}
bar();
Это происходит из-за того, что называется подъемом!
Есть два способа определения функций: функция объявление и функция выражение. Разница раздражает и незначительна, поэтому давайте просто скажем вот что немного неверно: если вы пишете как function name() {}
, это объявление, а когда вы пишете как var name = function() {}
(или анонимную функцию, назначенную для return и тому подобное), это функция выражение.
Во-первых, давайте посмотрим, как обрабатываются переменные:
var foo = 42;
//the interpreter turns it into this:
var foo;
foo = 42;
Теперь, как обрабатываются объявления функции:
var foo = 42;
function bar() {}
//turns into
var foo; //Insanity! It's now at the top
function bar() {}
foo = 42;
Операторы var
«забрасывают» создание foo
на самый верх, но еще не присваивают ему значение. Объявление функции идет следующим в строке, и, наконец, значение присваивается foo
.
А что насчет этого?
bar();
var foo = 42;
function bar() {}
//=>
var foo;
function bar() {}
bar();
foo = 42;
Только объявление foo
перемещается вверх. Присваивание происходит только после того, как был сделан вызов bar
, где он был до того, как произошел подъем.
И напоследок для краткости:
bar();
function bar() {}
//turns to
function bar() {}
bar();
А что насчет функций выражений?
var foo = function() {}
foo();
//=>
var foo;
foo = function() {}
foo();
Как и обычные переменные, сначала foo
объявляется в наивысшей точке области видимости, а затем ему присваивается значение.
Посмотрим, почему второй пример выдает ошибку.
bar();
function bar() {
foo();
}
var foo = function() {}
//=>
var foo;
function bar() {
foo();
}
bar();
foo = function() {}
Как мы видели ранее, поднимается только создание foo
, а присваивание происходит там, где оно появилось в «исходном» (не поднятом) коде. Когда вызывается bar
, это происходит до того, как foo
присваивается значение, поэтому foo === undefined
. Теперь в теле функции bar
это как если бы вы выполняли undefined()
, что вызывает ошибку.
person
Zirak
schedule
30.09.2011