Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Переопределение локальных переменных во вложенных функциях (https://javascript.ru/forum/misc/26662-pereopredelenie-lokalnykh-peremennykh-vo-vlozhennykh-funkciyakh.html)

Ssipak 17.03.2012 09:25

Переопределение локальных переменных во вложенных функциях
 
Доброго времени суток!
Столкнулся проблемой, чтобы было понятнее, убрал всё лишнее.
(function() {
  var a=1;
  (function(){
    alert(a); // Ожидал получить 1, выводит "undefined"
    var a=2;
    (function(){
      alert(a); // Выведет 2.
    })();
  })();
  alert(a); // Выведет 1.
}) ();

Требуется, чтобы внутренняя переменная локальной для функии, в которой она определена.
Ожидал, что до определения внутренней переменной будет видна внешняя, но, судя по всему, если в функции определена локальная переменная в любой позиции (хоть в конце функции), то другие одноименные переменные из внешней области видимости недоступны.
Понимаю, что происходит, понимаю, как обойти, не понимаю, почему именно так. Буду признателен, если получу ссылку на статью, где упоминается этот нюанс.

devote 17.03.2012 09:49

(function() {
  var a=1;
  (function(){
    alert(a);
    a=2;
    (function(){
      alert(a);
    })();
  })();
}) ();

nerv_ 17.03.2012 10:07

Цитата:

Сообщение от Ssipak
Буду благодарен за разъяснение причины такого поведения скрипта.

переопределение/замещение переменной "a" внешней функции локальной переменной с таким же именем

Ssipak 17.03.2012 10:09

Спасибо за внимание и быстрый ответ :)
Скрипт работает, но не так, как требуются. Уточню в шапке требования.

melky 17.03.2012 11:35

Цитата:

Сообщение от Ssipak (Сообщение 163598)
Доброго времени суток!
Столкнулся проблемой, чтобы было понятнее, убрал всё лишнее.
(function() {
  var a=1;
  (function(){
    alert(a); // Ожидал получить 1, выводит "undefined"
    var a=2;
    (function(){
      alert(a); // Выведет 2.
    })();
  })();
  alert(a); // Выведет 1.
}) ();

Требуется, чтобы внутренняя переменная локальной для функии, в которой она определена.
Ожидал, что до определения внутренней переменной будет видна внешняя, но, судя по всему, если в функции определена локальная переменная в любой позиции (хоть в конце функции), то другие одноименные переменные из внешней области видимости недоступны.
Понимаю, что происходит, понимаю, как обойти, не понимаю, почему именно так. Буду признателен, если получу ссылку на статью, где упоминается этот нюанс.

Извините, но перекрытие глобальных переменных глобальными даже в школе проходят (Паскаль, процедуры и функции).

Раньше можно было добраться до верхней области видимости с помощью свойства __parent__, но сейчас оно удалено.Так что - никак.

Rootpassword 17.03.2012 11:39

Ваш код выводит undefined, потому что эквивалентен следующему
(function() {
  var a=1;
  (function(){
    var a; //  оно undefined, 
    alert(a); // Ожидал получить 1, выводит "undefined"
    a=2;
   //  alert(a); // тут уже 2
    (function(){
      alert(a); // Выведет 2.
    })();
  })();
  alert(a); // Выведет 1.
}) ();

Это логично, если прочитать о том, как ищутся в js переменные в вложенных областях видимости и про объект вызова заодно

Ssipak 17.03.2012 12:44

Цитата:

Сообщение от Rootpassword (Сообщение 163617)
Ваш код выводит undefined, потому что эквивалентен следующему
(function() {
  var a=1;
  (function(){
    var a; //  оно undefined, 
    alert(a); // Ожидал получить 1, выводит "undefined"
    a=2;
   //  alert(a); // тут уже 2
    (function(){
      alert(a); // Выведет 2.
    })();
  })();
  alert(a); // Выведет 1.
}) ();

Это логично, если прочитать о том, как ищутся в js переменные в вложенных областях видимости и про объект вызова заодно

Спасибо большое за упоминание объекта вызова, по какой-то причине не знал о нём.

Ssipak 17.03.2012 12:50

Цитата:

Сообщение от melky (Сообщение 163614)
Извините, но перекрытие глобальных переменных глобальными даже в школе проходят (Паскаль, процедуры и функции).

Раньше можно было добраться до верхней области видимости с помощью свойства __parent__, но сейчас оно удалено.Так что - никак.

Вы меня тоже извините, но, судя по вашему ответу, вы не поняли темы. В любом случае, спасибо за внимание.

Ssipak 17.03.2012 12:53

В общем, спасибо Rootpassword, разобрался. Почитал тут и тут. Тема закрыта.


Часовой пояс GMT +3, время: 02:06.