var foo = '1',
bar = '2';
console.log(foo, bar, window.foo); //1, 2, undefined
(function(foo){
console.log(foo, bar); //2, 2
})(bar);
关于上述代码我有两个小问题:
为什么window.foo
未定义?默认情况下,并非所有全局变量都附加到窗口对象上吗?
为什么foo ===
2在闭包内?我知道我将原始bar
与别名foo
一起传递,2
,但在函数范围foo
之外仍然是1
。据我所知,原始foo
也可以从闭包内部访问。 “新foo”是否被优先考虑,因为它作为IIFE的论据被传递?
答案 0 :(得分:9)
为什么
window.foo
未定义?是不是所有“全局”变量都自动附加到窗口对象?
是的,全局变量成为window
的属性,但代码不会在您的小提琴中的全局范围内运行。它在load
事件处理程序中运行(请参阅左侧的第二个复选框,它显示“onLoad”)。它在全球范围内运行:http://jsfiddle.net/GbeDX/1/
为什么
foo === 2
在封闭内? [...]据我所知,原始foo
也可以从闭包内部访问。
不,它不能。 参数 foo
阴影变量foo
。如果它是全局变量,您可以使用window.foo
访问它。
答案 1 :(得分:1)
是。我的猜测是你在一些 debug 环境中执行该代码,如Firebug,jsFiddle等,它隐含地将该代码包装到范围中
将值2
传递给该自执行匿名函数,并通过本地参数foo
访问该值。由于范围链查找始终工作 bottom-> up ,因此该变量名称的解析将在本地范围停止,其中foo
被视为参数。
答案 2 :(得分:1)
window.foo === '1'
,除非你在另一个函数中运行它。foo === '2'
因为你声明foo
作为函数的输入参数。如果您尚未决定声明具有相同名称的本地范围变量,则可以访问全局范围的foo
。答案 3 :(得分:0)
foo
视为undefined
,因为您在调试环境中运行脚本,例如firebug或jsfiddle(相关https://stackoverflow.com/a/11572991/975520)foo
会覆盖变量foo
。但它仍然是一个全局变量,因此您可以将其用作window.foo
。