JavaScript关闭与本地

时间:2014-02-25 14:55:51

标签: javascript closures scope-chain

我有一个Javascript主文件,它被一个立即调用的闭包所包围(以免污染'global':

(function () {
"use strict";
   var closureVariable = [];
...
}());

当从函数头中删除变量时,我发出了一个简单的,带头的编码错误,这样我的代码就有了逗号而不是分号:

function fred () {
    var i,

    closureVariable = [1,2,3,4];
    confused();
}
function confused () {
    console.log(closureVariable);     // Prints '[]'
}

当然'var i'行上缺少的分号就是问题所在。然而,我认为应该发生的行为是我现在本地定义的变量'closureVariable'应该遮蔽更高级别的范围定义,并且我的本地定义变量的值应该可用于范围链中较低的函数(也就是说,'confused'函数应该打印出'[1,2,3,4]';

我在这里不了解Javascript范围链?

3 个答案:

答案 0 :(得分:3)

var i,

    closureVariable = [1,2,3,4];

生成两个新变量,可在fred函数和此范围中定义的函数中使用。

这些变量与fred范围之外定义的任何变量完全不同,即使它们碰巧具有相同的名称。

此处的阴影意味着名为"closureVariable"的变量会阻止对外部作用域中具有相同名称的变量的任何直接访问。

答案 1 :(得分:3)

您期望的是动态范围。这是一种有效的语言设计选择,尽管今天被广泛认为是劣等的。这不是Javascript的作用。与许多流行语言一样,Javascript使用词法范围。这意味着confused的范围不被视为fred的子范围,因为其定义不在fred的定义范围内。 fred调用confused的事实无效。

答案 2 :(得分:1)

当您通过省略分号重新定义closureVariable时,它仅在fred函数的上下文中重新定义。混淆函数存在于闭包的上下文中,因此它仍然可以看到原始的closureVariable。如果你在fred函数中定义了你的混淆函数,它会看到新的closureVariable并打印[1,2,3,4]

(function () {
  "use strict";
  var closureVariable = [];
  function fred () {
   var i,

   closureVariable = [1,2,3,4];

   function confused () {
      console.log(closureVariable);     
   }

   confused();  // print [1,2,3,4]
  }
 })();

或者如果你想从fred()

之外打电话混淆
(function () {
  "use strict";
  var closureVariable = [];
  var confused;

  function fred () {
   var i,

   closureVariable = [1,2,3,4];

   confused = function () {
      console.log(closureVariable);     
   }  
  }

  confused();  // print [1,2,3,4]
 })();
相关问题