关闭数量? (语义澄清)

时间:2012-10-15 16:13:46

标签: javascript closures

考虑以下JavaScript:

<script>
function Ninja() {
   var feints = 0;
    this.getFeints = function() {
        return feints;
    }

    this.feint = function() {
        feints++;
    }

    this.increaseByTwo = function() {
        feints = feints + 2;
    } 
}

var ninja = new Ninja();
ninja.feint();

console.log(ninja.getFeints());  //outputs one
ninja.increaseByTwo();
console.log(ninja.getFeints());  // outputs three
</script>

我是否正确地说上面的代码创建了四个闭包

  • 一个忍者 - 这有点无关紧要。
  • Ninja内部的每个内部功能都有一个。这三个闭包中的每一个都指向同一个东西。

或者JavaScript会创建两个闭包

  • 一个忍者 - 这有点无关紧要
  • 一个用于三个内部功能。三个内部函数共享相同的闭包。

3 个答案:

答案 0 :(得分:2)

所有三个内部函数都有一个指向同一环境的闭包,因此里面有变量。这通常是the whole point of having closures

  

在计算机科学中,闭包(也是词汇封闭或功能   closure)是一个函数或函数的引用   引用环境 - 存储对每个引用的引用的表   该函数的非局部变量(也称为自由变量)。1   闭包 - 与普通函数指针不同 - 允许函数访问   那些非局部变量,即使在其直接调用之外也是如此   词汇范围。

请注意,这是内存泄漏的常见原因,因为您并不总是意识到您正在保留这些引用。

查看Google's Javascript Style Guide says about closures

  

然而,要记住的一件事是闭包保持一个指针   到它的封闭范围。因此,将闭包附加到DOM   element可以创建循环引用,从而产生内存泄漏。

答案 1 :(得分:1)

只是,

  

忍者内部的每个内部功能一个

如果您要创建大量Ninja s,那么使用Ninja的{​​{1}}扩展是明智的。

所以,做:

prototype

http://jsfiddle.net/ZM3tH/

答案 2 :(得分:0)

执行该代码时会发生什么?让我们逐步完成它:

  1. 您声明了Ninja构造函数。在全局变量范围内。
  2. 您调用Ninja构造函数
    1. 这将创建一个新的变量环境(包含feints),该环境位于声明Ninja的全局范围内。
    2. 创建了三个匿名函数,指向该变量环境。
    3. 完成了一些任务并返回了对象。
  3. 垃圾收集器会检查它是否可以收集Ninja的变量环境:不,因为仍有三个函数可以使用并且可以使用它。
  4. 您在ninja上执行方法。每个,
    1. 创建一个新的空变量环境,该环境位于声明函数的范围内
    2. 该功能可以执行某些操作,之后将对本地环境进行垃圾回收。
  5. 什么是关闭?根据我的理解,Ninja()的私有变量环境比函数调用更长。因此,您的代码只会创建一个闭包。

    请参阅@ dystroy的答案,它提供了有用的信息。如果我在某处使用技术上不正确的术语,我很抱歉。 Afaik,EcmaScript规范称为“变量环境”,我称之为执行上下文,范围是词汇环境 - 请参阅section 10