这是Closure的正确陈述吗?

时间:2012-10-05 10:15:20

标签: javascript closures

引自Stoyan Stefanov的面向对象的JavaScript(第84页):

enter image description here

  

如果你在a点,你就在全球空间里。如果你在b点,那就是   在函数F的空间内,您可以访问全局空间和   F空间。 如果您位于功能N内的c点,则可以访问   全球空间,F空间和N空间你无法从a到b,因为   b在F外面是不可见的。但如果你愿意,你可以从c到b,或从N到b。该   有趣的事情 - 关闭 - 当某种方式N突破F并结束时发生   在全球范围内。“

我认为上面的粗体句子应该改为“如果你在点c,它在函数N里面,那么你可以访问全局空间和N空间”(F空间不应该包含,因为点c只能访问N空间和全局范围G.)。

我是对的吗?感谢。

5 个答案:

答案 0 :(得分:2)

不,我认为它的含义是N是一个从函数F返回的函数,因此可以访问(通过闭包)变量bF内声明。例如(live example):

function F() {
    var b = 10;
    return function () {
        console.log(b);
    };      
}

var N = F(); //N is a reference to the anonymous function returned from F

N(); //logs '10' because we still have access to b (because of the closure)

答案 1 :(得分:1)

不,你不对。

虚线圆圈应该代表N的实际范围,位于F内。

答案 2 :(得分:1)

不,在c点,你实际上可以访问他的F空间。

这方面的一个例子:

function F() {

  var b = 42;

  function N() {
    alert(b);
  }

  return N;

}

// get a reference to the function N in the global scope:
var n = F();
n(); // shows 42

答案 3 :(得分:1)

不,你不对,请看下面的代码。

// the global space
var g = 'g';

function F() {
  // the F space
  var a = 'a';
  function N () {
    // the N space
    // here you could access g in the global space and a in the F space.
    var c = 'c';
    console.log(g, a);
  }
}

答案 4 :(得分:1)

正如其他人所说,没有。

关于闭包的关键在于,对内部函数的外部引用不仅使内部函数保持活动状态,而且还允许它访问创建它的外部环境,即使外部环境来自于执行完成并返回的函数。

我认为如果在N中显示蓝色F并且在N之外显示虚线版本(对F的引用),则该图表将更好地说明闭包。

引用陈述的最后一句也可以改进:

  

有趣的事情 - 闭包 - 在F之外存在对N的外部引用时发生。

请注意,此版本避免提及全局空间。任何外部范围都足以形成一个闭包。

声明可以进一步说,允许形成闭包的机制是抑制垃圾收集。

警告:在网络和书籍中有许多关于“封闭”的错误定义和描述。 Stack Overflows的“闭包”的当前标签wiki条目就是一个很好的例子。