33

Javascript闭包定义说:

“闭包”是一个表达式(通常是一个函数),它可以具有自由变量以及绑定这些变量的环境(即“关闭”表达式)。

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

4

4 回答 4

37

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

来源 :

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

于 2012-10-17T13:02:55.717 回答
7

“免费翻译”可以是:"out of scope" - variables.

由于 ECMAscript 使用词法作用域,自由变量是在父作用域中定义并通过作用域链搜索查找的变量。

(function _outerScope() {
    var foo = 42;

    (function _innerScope() {
        var bar = 100;

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

在上面的例子中,是上下文中的foo一个自由变量_innerScope。如果我们快速浏览一下 ECMAscript 的基本概念,就会变得非常明显。

上下文链接到一个激活对象(在 ES3 中),分别链接到一个词法环境记录(在 ES5 中),其中包含诸如:function declarationsvariables declared with varformal paramters、以及对所有父激活对象/词法环境的引用。如果需要访问某个变量,ECMAscript 引擎会首先从当前的Context本身中查找AO / LE ;如果在那里找不到,它会查看父AO的 / LE的。

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

于 2012-10-17T13:08:50.027 回答
2

举个例子:

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

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

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

于 2012-10-17T13:05:10.317 回答
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)
}

现在你可以掌握

术语自由变量是指函数中使用的变量,这些变量既不是局部变量也不是该函数的参数。

于 2021-01-29T09:20:50.177 回答