【问题标题】:confusion of javascript closurejavascript闭包的混淆
【发布时间】:2014-02-10 12:25:56
【问题描述】:

我已经证明我并不真正理解 javascript 闭包,并且我被以下代码弄糊涂了。我以为 fxn 会访问外部 foo,但它实际上打印出“欠精细”。为什么??

var foo = "hello";
function fxn(){
   alert(foo);
   var foo = "test"
}

fxn();

【问题讨论】:

  • 无法复制。它将记录 undefined 但警告 hello

标签: javascript closures


【解决方案1】:

这是因为在 JavaScript 中,变量会得到hoisted,这意味着

变量在创建时被初始化为undefined。一个变量 Initialiser 在以下情况下被分配其 AssignmentExpression 的值 VariableStatement执行,而不是在创建变量时。(ES5 §12.2)

因此,从语义上讲,您的代码将等同于以下...

var foo = "hello";
function fxn(){
   var foo; //Variables are initialised to undefined when created
   alert(foo);
   foo = "test"; //A variable with an *Initialiser* is assigned the value of its *AssignmentExpression* when the *VariableStatement* is **executed**
}

fxn();

【讨论】:

    【解决方案2】:

    您在函数之外定义变量foo。如果你重复调用var,你会在函数内部重新定义变量,它会失去分配。

    去掉函数中的var,将foo访问到函数fnx中。

    var foo = "hello";
    function fxn(){
       alert(foo);
       foo = "test";
    }
    
    fxn();
    

    Jsfiddle

    【讨论】:

    • 你能再解释一下吗?
    • 您在函数之外定义变量“foo”。如果你重复调用“var”,你会在函数内部重新定义变量,它会失去分配。
    • 我会在 R3tep 中添加:1) 重新定义 in 方法会隐藏外部定义,但是 ... 2) 您在定义变量之前使用它 => 'undefined'(另请参见 C5H8NNaO4 答案)
    • @Hezi 对于我来说,foo 在这个例子中是一个全局变量 (link)。所以变量被定义并且在alert()被更新之后。
    • @R3tep 正确。但在最初的问题中,变量是使用 'var' 重新定义的。
    猜你喜欢
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    • 2012-06-30
    相关资源
    最近更新 更多