Использование var во вложенной функции для объявления переменной с тем же именем, что и параметр parent

#javascript

#javascript

Вопрос:

Я использую JavaScript для написания некоторого кода и обнаружил неожиданное поведение.

Я использую вложенную функцию g внутри f . f имеет параметр с именем m . При использовании и объявлении переменной внутри g с тем же именем происходит что-то странное:

 var f = function(m) {
    var g = function() {
        alert(m);
        var m = 0;
    };
    g();
};
f(1);
  

Результатом этого кода будет undefined , вместо 1 того, что я ожидал.

Перемещение alert инструкции ниже var строки приведет к ответу 0 , который имеет смысл.

Я полагаю, это связано с тем, что JavaScript использует функции только в качестве замыкания имени, var m будет присоединен к функции g с объявлением, но m еще не назначен во время alert .

Но я не уверен в этом, потому что, если функция не вложена, ее поведение мне кажется приятным:

 var g = function(m) {
    alert(m);
    var m = 0;
};
g(1);
  

привело бы к 1 .

Кто-нибудь может объяснить? Спасибо.

Комментарии:

1. Существует ли какой-либо другой код, который может повлиять на это? Поведение здесь не такое, как вы описываете: jsfiddle.net/QvcqU

2. @shanethehat: извините, я имел в виду undefined .

3. Когда я запускаю ваш первый блок кода, я получаю undefined.

4. @herostwist: да, это undefined . Я отредактировал вопрос.

5. Причина, по которой второй выдает 1, заключается в том, что у вас есть m в качестве формального параметра, затем передайте 1 функции, чтобы ей присваивалось значение при вызове функции. Позже m устанавливается в 0, когда обрабатывается присвоение m=0.

Ответ №1:

Javascript использует область видимости функции, что означает, что область видимости переменных не похожа на область видимости блока C, входящую и выходящую из области видимости в соответствии с {} , а скорее объекты входят и выходят из области видимости в соответствии с началом и окончанием функций. Таким образом, каждая локальная переменная, которую вы определяете в функции, объявляется с начала выполнения этой функции и будет иметь тип undefined до тех пор, пока вы не инициализируете ее в своей функции.

Таким образом, при g выполнении, поскольку в какой-то момент будет создана локальная переменная m , среда выполнения уже объявляет, что существует локальная m (которая, очевидно, скрывает внешний m f функции) с типом undefined с начала g выполнения

Смотрите https://developer.mozilla.org/en/JavaScript/Reference/Scope_Cheatsheet это объясняет, что при выполнении этого действия var varName переменная поднимается в верхнюю часть области видимости функции. На этой странице много отличных примеров, вот одна цитата, которая подводит итог:

Каждое определение переменной на самом деле является объявлением переменной в верхней части ее области видимости и присвоением в месте, где находится определение.

Комментарии:

1. Хотя это объяснение звучит разумно, я не думаю, что оно отвечает на вопрос, а именно, почему параметры обрабатываются иначе, чем определения во внешней области видимости. Я предполагаю, что ответом вполне может быть: именно так оно и есть.