在全局“this”对象上使用“for in”循环的奇怪行为

时间:2014-03-31 00:19:46

标签: javascript

有人可以解释在全局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);

我不理解的事情是

  1. 为什么this会获得一个新属性?

  2. 为什么值是字符串,即使我从不给出任何字符串值?

  3. 另外,为什么它在浏览器中有所不同? (如果没有自我解释给出1和2的答案)

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"