Почему глубоко вложенные функции могут обращаться к переменным верхнего уровня? - PullRequest
3 голосов
/ 25 декабря 2011

Я занимался чтением javascript и понял, что замыкание имеет доступ только к закрывающему элементу, «обёртывающему» его, или, можно сказать, его непосредственный родитель. Теперь я немного поиграл, и в я вижу этот jsfiddle , что даже глубоко вложенные функции имеют доступ к определенным переменным вверх.

Может кто-нибудь объяснить это? Или объясните, в чем я не прав?

http://jsfiddle.net/tPQ4s/
function runNums() {
    this.topVar = 'blah';
    return function(){
        (function() {                    
            (function() {
                console.log(topVar);
            })();
        })();
    }
}

var someFunc = runNums();
someFunc(); 

Ответы [ 4 ]

6 голосов
/ 25 декабря 2011

Не вдаваясь слишком глубоко в детали, closure технически описывает array like variable в так называемом Объекте активации , который обрабатывается из движка javascript.ActivationObject содержит переменных, объявленных var, объявлениями функций и формальными параметрами .

Это означает, что в любое время новая функция (-context), внутри создается новый объект активации.Этот объект является частью нового Execution Context, типичный EC выглядит следующим образом:

  • эта переменная контекста
  • Объект активации
  • [[Scope]]

Интересная часть здесь - [[Scope]].Эта переменная содержит все объекты активации родительского контекста all и заполняется при вызове EC.Итак, теперь, когда функция хочет получить доступ к переменной, процесс разрешения имен сначала просматривает свой собственный объект активации, если ничего не найдено, поиск продолжается в «цепочке областей действия», которая является просто индексированным поиском через нашу [[Scope]] переменную (которая опять же является массивом родительских контекстов).Вот почему мы также много говорим о «лексической области видимости» в ECMA- / Javascript.

Примечание. Приведенное выше поведение не описано полностью, для этого потребуется несколько страниц текста.Также описывается спецификация ECMAscript3 262.В ES5 все немного по-другому, но все равно примерно одно и то же

4 голосов
/ 25 декабря 2011

Это потому, что цепочка проходит дальше до верхнего контекста.
В этом примере это будет:

window < runNums < anonymous < anonymous < anonymous

Переменные, живущие в любом из них, будут доступны в последней анонимной функции,В runNums будут доступны только переменные, живущие в runNums или окне.В первой анонимной функции будут доступны только ее переменные и переменные, которые находятся в runNums или window и т. Д.

0 голосов
/ 09 мая 2017

Глубоко вложенные функции не были выполнены. Вы не вернули их для выполнения.

0 голосов
/ 25 декабря 2011

это здесь не что иное, как объект Window.

Здесь runNums - это глобальная функция, а runNums () равно window.runNums () . Так что это это окно и this.topVar это window.topVar . Очевидно, он будет доступен из любого места.

Попробуйте и увидите разницу

var someFunc = new runNums();
someFunc();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...