什么是自由变量?

时间:2012-10-17 13:00:38

标签: javascript closures free-variable

Javascript闭包定义说:

  

“闭包”是一个可以免费的表达式(通常是一个函数)   变量以及绑定这些变量的环境   (“关闭”表达式)。

有人可以向我解释自由变量的概念吗?这个概念是Javascript特定的还是适用于其他语言?

4 个答案:

答案 0 :(得分:27)

自由变量只是既未在本地声明也未作为参数传递的变量。

Source :

  

在计算机编程中,术语自由变量是指变量   在函数中使用,不是局部变量,也不是参数   function。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的变量:在同一范围内声明的另一个函数将共享同一个变量。

答案 1 :(得分:2)

“免费翻译”可以是:"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 Record (在ES5中),其中包含的东西例如:function declarationsvariables declared with varformal paramters,以及对所有父激活对象 / Lexical Environments 的引用。如果需要访问变量,ECMAscript引擎将首先从当前 Context 本身查看 AOs / LEs ;如果在那里找不到,它会查看父 AO 的/ LE

由于任何 Context 将此数据存储在类似数组的结构中(不要忘记我们在这里讨论的是实现级别,而不是Javascript本身),我们是谈论Lexical Scope,因为我们按顺序搜索所有父上下文

答案 2 :(得分:0)

举个例子:

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

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

定义的变量有一个闭包变量。它可以在闭包本身使用,但不是全局命名空间的一部分。

答案 3 :(得分:0)

我不记得我读了多少 JS 书籍并修改了一些有闭包主题的主题。

答案只是对已接受答案的补充。

以下示例摘自Modern JavaScript for the Impatient, Cay Horstmann

// 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)
}

现在你可以理解

的意思了 <块引用>

术语自由变量是指在函数中使用的变量 不是该函数的局部变量或参数。