函数范围和全局变量

时间:2013-04-25 17:52:33

标签: javascript

var foo = '1',
    bar = '2';

console.log(foo, bar, window.foo); //1, 2, undefined

(function(foo){
    console.log(foo, bar); //2, 2
})(bar);

关于上述代码我有两个小问题:

  1. 为什么window.foo未定义?默认情况下,并非所有全局变量都附加到窗口对象上吗?

  2. 为什么foo === 2在闭包内?我知道我将原始bar与别名foo一起传递,2,但在函数范围foo之外仍然是1。据我所知,原始foo也可以从闭包内部访问。 “新foo”是否被优先考虑,因为它作为IIFE的论据被传递?

  3. http://jsfiddle.net/GbeDX/

4 个答案:

答案 0 :(得分:9)

  

为什么window.foo未定义?是不是所有“全局”变量都自动附加到窗口对象?

是的,全局变量成为window的属性,但代码不会在您的小提琴中的全局范围内运行。它在load事件处理程序中运行(请参阅左侧的第二个复选框,它显示“onLoad”)。它在全球范围内运行:http://jsfiddle.net/GbeDX/1/

  

为什么foo === 2在封闭内? [...]据我所知,原始foo也可以从闭包内部访问。

不,它不能。 参数 foo 阴影变量foo。如果它是全局变量,您可以使用window.foo访问它。

答案 1 :(得分:1)

  1. 是。我的猜测是你在一些 debug 环境中执行该代码,如Firebug,jsFiddle等,它隐含地将该代码包装到范围中

  2. 将值2传递给该自执行匿名函数,并通过本地参数foo访问该值。由于范围链查找始终工作 bottom-> up ,因此该变量名称的解析将在本地范围停止,其中foo被视为参数。

答案 2 :(得分:1)

  1. window.foo === '1',除非你在另一个函数中运行它。
  2. 在闭包内部的
  3. foo === '2'因为你声明foo作为函数的输入参数。如果您尚未决定声明具有相同名称的本地范围变量,则可以访问全局范围的foo

答案 3 :(得分:0)

  1. 是。您可能会将变量foo视为undefined,因为您在调试环境中运行脚本,例如firebug或jsfiddle(相关https://stackoverflow.com/a/11572991/975520
  2. 否。参数foo会覆盖变量foo。但它仍然是一个全局变量,因此您可以将其用作window.foo