Как происходит всплытие переменной?

У меня есть такая функция. В итоге в консоль выводит 10.

var foo = 1; 
function bar() { 
    if (!foo) { 
        var foo = 10; 
    } 
    console.log(foo); 
} 
bar(); //--> 10


Вопрос: каким образом в консоль выводится 10? Получается, что натыкаясь на foo в самом условии if, переменная foo объявляется в пределах функции, потом браузер ищет переменную foo в пределах функции, находит undefined, которое благодаря логическому оператору "не" переводится в true. Выводится 10. Или как?

Просто где-то еще читаю, что всплытие всегда объявляет глобальную переменную (то есть не в самой функции), ну если объявляется глобальная переменная, я не понимаю как тогда происходит вывод 10.
  • Вопрос задан
  • 344 просмотра
Решения вопроса 1
sergiks
@sergiks Куратор тега JavaScript
♬♬
Внутри функции наверх выплывает только объявление локальной переменной var foo;

var foo = 1; // можно стереть
function bar() { 
    var foo; // всплыло сюда. Этот foo – иной, чем верхний foo!
    if (!foo) { // тут foo undefined,  !foo === true
        foo = 10; // выполняется, назначается 10
    } 
    console.log(foo); // вывели 10
} 
bar(); //--> 10
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Объявления переменных и функций всплывают на верх области видимости, у var и function (та что declaration) - это внешняя функция или модуль (если на верхнем уровне дело происходит), у let и const - блок, то есть после всплытия, внутри движка Ваш код будет выглядеть так:
var foo; 
function bar() {
    var foo; // эта foo перекрывает foo из внешней области видимости, и поэтому в функции используется она
    if (!foo) { 
        foo = 10; 
    } 
    console.log(foo); 
}
foo = 1;
bar(); //--> 10


Так же важно знать, что хотя let и const всплывают наверх блока, но использовать их до фактического места объявления нельзя, так будет ошибка:
{
    console.log(x); // ReferenceError: Cannot access 'x' before initialization
    let x;
}
Это механизм защиты "от дурака" и называется он "мертвое всплытие". По этому всегда лучше использовать let или const, притом const предпочтительнее если переменная не меняется, так как дает больше гарантий.
Ответ написан
dollar
@dollar
Делай добро и бросай его в воду.
Всплытие происходит в начало функции (т.е. bar), где бы внутри функции вы ни объявили переменную через var.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы