Именованные функции в Javascript доступны до объявления, но функциональные литералы не являются
Я пытаюсь понять, как это работает. Когда я ссылаюсь на именованную функцию Javascript, которая еще не была объявлена, в некоторых случаях она работает. Но если я использую литерал функции, это не так, но и с ошибкой ReferenceError
,
function works() {
var works_ref = foo;
function foo() {
console.log('ok');
};
console.log('works ' + works_ref);
}
function fails() {
var fails_ref = foo;
var foo = function() {
console.log('ok');
};
console.log('fails ' + fails_ref);
}
works();
fails();
Это возвращает
"works function foo() {
console.log('ok');
}"
"fails undefined"
Мне интересно, как работает первый пример - это интерпретируемый язык, не скомпилированный, так что я ожидаю, что любой вид прямой ссылки потерпит неудачу - и почему второй пример не генерирует ReferenceError
?
2 ответа
function foo() {
console.log('ok');
};
Это называется объявлением функции. Это будет обработано во время компиляции. Итак, JavaScript знает, что есть функция с именем foo
, Вот почему он назначает объект функции здесь
var works_ref = foo;
Во втором случае
var foo = function() {
console.log('ok');
};
foo
переменная, которая объявляется позже в функции Итак, из-за подъема,
var fails_ref = foo;
осознает тот факт, что foo
определяется где-то в функции, но она не знает его действительного значения. Потому что присвоение значения var foo = function() {}
происходит во время выполнения. Вот почему значение по умолчанию undefined
используется для foo
до фактического выполнения оператора присваивания.
Это связано с подъемом, что на самом деле происходит, это:
function works() {
var works_ref = undefined;
function foo() {
console.log('ok');
};
works_ref = foo;
console.log('works ' + works_ref);
}
function fails() {
var fails_ref = undefined,
foo = undefined;
fails_ref = foo; // <---------- note this line.
foo = function() {
console.log('ok');
};
console.log('fails ' + fails_ref);
}