Что такое свободные переменные?

Определение закрытия Javascript гласит:

"Закрытие" - это выражение (обычно функция), которое может иметь свободные переменные вместе со средой, которая связывает эти переменные (которая "закрывает" выражение).

Может кто-нибудь объяснить мне понятие свободных переменных? Является ли эта концепция Javascript специфичной или применима также и к другим языкам?

4 ответа

Решение

Свободные переменные - это просто переменные, которые не объявлены ни локально, ни как параметр.

Источник:

В компьютерном программировании термин свободная переменная относится к переменным, используемым в функции, которые не являются ни локальными переменными, ни параметрами этой функции. 1 Термин нелокальная переменная часто является синонимом в этом контексте.

В замыканиях javascript это просто переменные, которые функция принимает (чтение и запись) во вложенной области видимости, где объявляется замыкание или в родительской области видимости.

Посмотрите на этот пример из реального мира:

Gol.prototype._ensureInit = function() {
    ...
    var _this = this;
    var setDim = function() {
        _this.w = _this.canvas.clientWidth;
        _this.h = _this.canvas.clientHeight;
        _this.canvas.width = _this.w;
        _this.canvas.height = _this.h;
        _this.dimChanged = true;
        _this.draw();
    };
    setDim();
    window.addEventListener('resize', setDim);
    ...
};

В этом примере точки закрытия из setDim функция к переменной _this заявлено в прилагаемой области (_ensureInit функция). Эта переменная не объявлена ​​в setDim ни прошло. Это "свободная переменная".

Обратите внимание, что _this не становится переменной функции setDim: другая функция, объявленная в той же области видимости, будет использовать ту же переменную.

"Свободный перевод" может быть: "out of scope" - variables,

Поскольку ECMAscript использует лексическую область видимости, свободная переменная - это переменная, которая была определена в родительской области видимости и проверяется поиском в цепочке областей действия.

(function _outerScope() {
    var foo = 42;

    (function _innerScope() {
        var bar = 100;

        console.log( foo + bar ); // 142
    }());
}());

В приведенном выше примере foo является свободной переменной в контексте _innerScope, это становится очень очевидным, если мы быстро взглянем на основные понятия ECMAscript.

Контекст связан с объектом активации (в ES3), соответственно, с записью Lexical Enviroment (в ES5), которая содержит такие вещи, как: function declarations, variables declared with var а также formal paramters, а также ссылка на все родительские объекты активации / лексические среды. Если необходимо получить доступ к переменной, механизм ECMAscript сначала изучит AO / LE из самого текущего контекста; если это не может быть найдено там, это смотрит на родительские AO's / LE' s.

Поскольку в любом контексте эти данные хранятся в массивоподобной структуре (не забывайте, что здесь речь идет об уровне реализации, а не о самом Javascript), мы говорим о Lexical Scope, потому что мы ищем все родительские контексты по порядку.

В качестве примера:

var myModule = (function (){
   var moduleVar; // closure variable

   return function(){
     // actual function
   }
})();

определенная переменная есть переменная замыкания. он может использоваться во всем самом замыкании, но не является частью глобального пространства имен.

Я не помню, сколько раз я читал книги по JS и пересматривал какую-то тему, в которой есть тема закрытия.

Ответ - это просто дополнение к принятому ответу.

Следующий пример взят из книги «Современный JavaScript для нетерпеливых», Кей Хорстманн.

      // text is a free variable of the arrow function.
const sayLater = (text, when) => {
  //         vv
  let task = () => console.log(text) // (heed no 'text' variable here) => console.log(text)
  setTimeout(task, when)
}

Теперь вы можете понять смысл

Термин «свободная переменная» относится к переменным, используемым в функции, которые не являются ни локальными переменными, ни параметрами этой функции.

Другие вопросы по тегам