2011-04-17 80 views
1

为什么验证码:到那里所有的JavaScript专家:为什么会发生这种情况?

function answer(x) { 
    function closure() { 
    var x = x || 42; 
    console.log(x); 
    } 
    closure(); 
} 
foo(); 

始终打印42

的逻辑将是像foo(31337)将打印31337,因为在closurex31337,所以x || 42将评估为31337。但这种情况并非如此。

我只是无法弄清楚这一点,所以我在这里张贴这个希望从那里的真正的JavaScript大师之一接受启示。

回答

4
function answer(x) { 
    function closure() { 
    var x = x || 42; 
    console.log(x); 
    } 
    closure(); 
} 
answer(20); 

闭合你的定义x作为一个局部变量。这意味着它会从链上更高的回答函数中将参数x遮蔽。既然你用var语句声明了x,它默认为undefined

然后x || 42undefined || 42这是42

这里的问题是,你使用相同的名称。如果你做x = x || 42这将是x = 28 || 42它将x设置为28.

区别是使用var语句创建一个名为x的新函数局部变量。一旦你这样做了,就没有办法引用范围链上的同名变量。

澄清解释器是如何工作的。事情是这样的:

function() { 
    var x = 52; 
    foo(); 
    function foo() { 
     ... 
    } 
} 

获取转换成

function() { 
    function foo() { 

    } 
    var x; 
    x = 52; 
    foo(); 
} 
+0

所以你说'var x = x || 42;'和var x是一样的东西; x = x || 42;',这意味着在执行'(...)'之前'var x =(...)''x'被声明为局部变量? – NeuronQ 2011-04-17 13:21:57

+0

@NeuronQ正好。澄清所有'var'语句被升到范围的顶部。请参阅编辑。 – Raynos 2011-04-17 13:22:28

+0

谢谢,现在真的有道理:) – NeuronQ 2011-04-17 13:29:46

3

var xvar x = x || 42;阴影的说法。 而且由于var ...总是在函数的开始处被分析 - 即在分配被执行之前,外部x在那里永远不可用。

这里有一个更好的例子:

(function(x) { 
    (function() { 
     alert(x); 
     var x = 'inside'; 
    })(); 
})(123); 

执行顺序基本上是:

  • 定义VAR x与价值undefined
  • 执行alert(x)
  • 分配'inside'x