Понимание глобального и локального охвата в Javascript

Я изучаю Javascript, используя Объектно-ориентированный JavaScript от Stoyan Stefanov

Он предлагает пример сравнения глобальной и локальной областей:

var a = 123;
function f() {
    alert(a);
    var a = 1;
    alert(a);
}
f();

В этом примере я ожидал, что первое предупреждение будет "123", а второе предупреждение - "1". Вот, Стоян говорит:

Вы можете ожидать, что первое предупреждение() отобразит 123 (значение глобальная переменная a), а вторая отображает 1 (локальный a). Это не тот случай. В первом предупреждении появится "undefined". Это потому что внутри функции локальная область важнее, чем глобальный охват. Таким образом, локальная переменная перезаписывает любую глобальную переменную с одно и то же имя. Во время первого предупреждения() a еще не определено (следовательно, значение undefined), но оно все еще существует в локальном пространстве.

Объяснение мне было непонятно, как локальная переменная может переписать глобальную переменную в первом предупреждении? Любые другие/разные объяснения будут оценены.

Ответ 1

Это не переопределение глобальной переменной. То, что происходит, называется "переменным подъемом". То есть, a var a; вставлен в верхней части функции.

Двигатель script изменяет ваш script следующим образом:

var a = 123;
function f() {
    var a;
    alert(a);
    a = 1;
    alert(a);
}
f();

Урок для изучения: всегда указывайте свои переменные перед их использованием. Некоторые скажут объявить все ваши переменные в верхней части функции.

Ответ 2

Простыми словами сначала рассматриваются все декларации, как переменных, так и функций. Таким образом, локальный var a по сути будет переопределять глобальную переменную только в локальной области и не будет иметь никакого значения, т.е. undefined. Поэтому первое предупреждение покажет undefined. Второе предупреждение покажет 1, как и после a = 1. Это происходит только локально, а глобальная переменная a будет иметь значение 123 - она ​​не будет изменена.

другой пример с использованием функции, чтобы показать, как она работает

 function show(){
    alert("I am global");
 }

 function f() {

    show();

    show = function(){
       alert("I am second");
    }  

    show();   

    function show(){
        alert("I am first");
    }

}
f();
show();