我有一个 Javascript 主文件,它包含在一个立即调用的闭包中(以免污染“全局”:

(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 作用域链有什么不理解的地方?

有帮助吗?

解决方案

你所期待的被称为 动态范围界定. 。这是一种有效的语言设计选择,尽管如今被广泛认为较差。这不是 Javascript 所做的。与许多流行语言一样,Javascript 使用 词汇范围. 。这意味着 confused的范围不被视为子范围 fred的,因为它的定义不在定义之内 fred. 。事实是 fred 来电 confused 没有影响。

其他提示

var i,

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

创建两个新变量,可在 fred 函数以及在此范围内定义的函数。

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

这里的阴影意味着你的变量名为 "closureVariable" 防止对外部作用域中具有相同名称的变量进行任何直接访问。

当您通过省略分号重新定义闭彩变量时,它仅在FRED功能的上下文中重新定义。困惑的函数存在于关闭的上下文中,因此它仍然看到原始的闭彩变化。如果您在Fred函数内定义了困惑的函数,它将看到新的闭合变性,并打印[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]
 })();
.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top