有人可以解释在全局this
对象的for-in循环中导致这种奇怪行为的原因吗?
在全球空间,请执行
for(var key in this) key;
结果是,为this
获取了一个新属性key
,其值为"key"
。
这在nodejs和rhino js引擎中发生,但在浏览器中,结果是 - window
被分配了一个值为key
的新属性"dispatchEvent"
我认为这是直接在控制台中输入的一些副作用,但是如果你在没有带有此命令的控制台的脚本中运行它,它会做同样的事情。
$ node -e "for (var key in this) key; process.stdout.write(this.key + '\n')"
然后我认为它与for循环的主体只有key;
有关,但是当你这样做时会发生同样的事情
for (var key in this) console.log(key);
我不理解的事情是
为什么this
会获得一个新属性?
为什么值是字符串,即使我从不给出任何字符串值?
另外,为什么它在浏览器中有所不同? (如果没有自我解释给出1和2的答案)
答案 0 :(得分:4)
为什么给这个新房产?
var key // == this.key in the global scope.
因为this
是全局范围,浏览器中为window
,nodejs中为global
,当您在全局范围内声明变量时,它将被添加到全局范围,它很有道理。
为什么值是字符串,即使我从不给出任何字符串值?
因为for ... in
将对象可枚举属性名称枚举为字符串。
现在你得到dispatchEvent
,因为它是这里的最后一个枚举属性。
另外,为什么它在浏览器中有所不同? (如果不是自我解释的话 答案为1和2)
浏览器有何不同?浏览器具有完全相同的行为,
打开控制台,尝试var foo="bar"
,然后输入console.log(this.foo)
。你会得到吧。
答案 1 :(得分:0)
因为JavaScript没有块范围,所以它具有功能范围。所以表达式var key
将在global
范围内声明,因为你在其中执行。
它获取值"dispatchEvent"
,因为它是全局this
中的最后一个迭代属性名称。
在浏览器控制台中尝试以下操作:
for (var key in window.location)
console.log(key);
最后一个枚举属性为"reload"
,因此变量key
将为global
变量,其值为"reload"
。