Подтвердить что ты не робот

Как работает нижняя область JavaScript

Я читал о JavaScript области и Подъем. Я видел образец, как показано ниже, и я сомневался в этом. Поэтому мне было интересно, как это работает.

var a = 1;
function b() {
    a = 10;
    return;
    function a() {}
}
b();
alert(a);

Код будет предупреждать 1! Но если мы исключим функцию "a() {}" , код будет предупреждать 10.

Итак, как это работает! Что здесь делает "функция a() {}" и как она влияет на область действия.

Я также не могу понять значение пустого "return;" в этом коде.

Итак, как этот код работает, полагаясь на области JavaScript?

4b9b3361

Ответ 1

Сначала, "пустой" return; оператор просто выходит из функции в этой точке, возвращая undefined. Это эквивалентно return undefined;.

Простой случай, если вы исключили часть function a(){}, заключается в том, что функция b() изменяет глобальную переменную a на 10, поэтому, когда вы предупреждаете значение a после запуска b() функция 10. Без этой внутренней функции все ссылки на a означают глобальную переменную.

Но с частью function a(){} эта функция объявляется внутри b(). Он локален для b(). Итак, у вас есть две разные a s: глобальная переменная, а локальная - в b(). Независимо от того, где внутри содержащейся функции появляется другой оператор функции, он обрабатывается JS-компилятором, как если бы он находился в верхней части функции. Поэтому, даже если строка function a(){} находится в конце содержащейся функции b(), что происходит, когда выполняется код:

var a = 1;              // declare a global variable a
function b() {
    function a() {}     // declare a local function a
    a = 10;             // update local a to be 10 instead of a function
    return;
}
b();
alert(a);  // show value of global a, which is still 1

Ответ 2

В дополнение к nnnnnn отличный ответ, я попытался представить ситуацию.

С function a(){} ваш код ведет себя следующим образом:

scope: window                         scope: b
      |                                   |
      | var a = 1;  //window.a = 1;       |
      |                                   |
      | function b() { -----------------> |
      |                                   | function a(){} // b.a(){} (hoisted to top)
      |                                   | a = 10;        // b.a = 10;
      |                                   | return;
      | } <------------------------------ |
      |                                   |
      | b();                              |
      | alert(a);  // alert(window.a);    |

Мы видим, что function a(){} поднимается в начало функции, потому что включает объявление. И если мы удалим function a(){}, код будет вести себя следующим образом:

scope: window                         scope: b
      |                                   |
      | var a = 1;  //window.a = 1;       |
      |                                   |
      | function b() { -----------------> |
      |                                   | a = 10;        // window.a = 10;
      |                                   | return;
      | } <------------------------------ |
      |                                   |
      | b();                              |
      | alert(a);  // alert(window.a);    |

Ответ 3

Ваш код функционально одинаков с этим кодом:

var a = 1;
function b() {
    var a = function() {}
    a = 10;
    return;
}
b();
alert(a);

Использование нотации function NAME() { ... } эффективно помещает это объявление функции в начале текущей области как локальное (в эту область) объявление.

на самом деле, если вы выполните

var a = 1;
var c= 2;
function b() {
    a()
    a = 10;
    return;
    function a() { alert(c) }
}
b();
alert(a);

Он выведет:

2
1

Лично я не использую такую ​​нотацию, я всегда явно использую назначения.

jsfiddle