简体   繁体   English

JavaScript关闭与本地

[英]JavaScript Closure vs. Local

I have a Javascript main file that is enclosed by an immediately-called closure (so as not to pollute 'global': 我有一个Javascript主文件,由一个立即调用的闭包括(以免污染'全局':

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

I made a simple, bone-headed coding error when removing a variable from a function header such that my code had a comma instead of a semicolon: 从函数头中删除变量时,我做了一个简单的,有头骨的编码错误,这样我的代码就有了逗号而不是分号:

function fred () {
    var i,

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

Certainly the missing semicolon on the 'var i' line was the problem. 当然,'var i'行上缺少的分号就是问题所在。 However the behavior I thought should happen is that my now locally-defined variable 'closureVariable' should have shadowed the higher-level scope definition, and the value of my locally-defined variable should have been available to functions lower down in the scope chain (that is, function 'confused' should have printed out '[1,2,3,4]'; 然而,我认为应该发生的行为是我现在本地定义的变量'closureVariable'应该遮蔽更高级别的范围定义,并且我的本地定义变量的值应该可用于范围链中较低的函数(也就是说,'confused'功能应该打印出'[1,2,3,4]';

What am I not understanding about Javascript scope chains here? 我在这里对Javascript范围链的理解是什么?

var i,

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

makes two new variables, available in the fred function and in functions defined in this scope. fred函数和此范围中定义的函数中提供了两个新变量。

Those variables are totally different from any variable defined outside the fred scope, even if they happen to have the same name. 这些变量与fred范围外定义的任何变量完全不同,即使它们碰巧具有相同的名称。

Shadowing, here, means that your variable named "closureVariable" prevents any direct access to the variable having the same name in the outer scope. 这里的阴影意味着名为"closureVariable"的变量阻止对外部作用域中具有相同名称的变量的任何直接访问。

What you are expecting is known as dynamic scoping . 您期望的是动态范围 This is a valid language design choice, though widely considered inferior today. 这是一种有效的语言设计选择,尽管今天被广泛认为是劣等的。 It's just not what Javascript does. 这不是Javascript的作用。 Like many popular languages, Javascript uses lexical scoping . 像许多流行语言一样,Javascript使用词法范围 That means confused 's scope is not considered a child scope of fred 's, because its definition is not inside the definition of fred . 这意味着confused的范围不被视为fred的子范围,因为它的定义不在fred的定义范围内。 The fact that fred calls confused has no effect. fred call confused的事实没有效果。

When you redefined the closureVariable by omitting semicolon it was redefined only in the context of fred function. 当您通过省略分号重新定义closureVariable时,它仅在fred函数的上下文中重新定义。 The confused function exist in the context of your closure, so it still sees the original closureVariable. 混淆函数存在于闭包的上下文中,因此它仍然可以看到原始的closureVariable。 If you had your confused function defined inside of the fred function it would see the new closureVariable and would print [1,2,3,4] 如果你在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]
  }
 })();

Or if you want to call confused from outside of fred() 或者,如果你想从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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM