出于好奇......
我有这个JS代码:
var someExternalArray = [{id: 1, name: 'a'}, {id: 2, name: 'b'}, {id: 3, name: 'c'}];
var newArray = []
//var item;
for (var i = 0; i < someExternalArray.length; i++){
item = new Object();
item.id = someExternalArray[i].id;
item.name = someExternalArray[i].name;
newArray.push(item);
}
alert('0:' + newArray[0].name + ',1:' + newArray[1].name + ',2:' + newArray[2].name);
注意注释var item
,它使循环中包含隐式声明的item
变量。
如果我在FireFox上运行此代码,则警告的结果为:0:a,1:b,2:c
如果我在Internet Explorer中运行相同的代码,结果是:
0:c,1:c,2:c
这是jsfiddle:https://jsfiddle.net/fvu9gb26/
当然,当我取消注释var item
时,它在每个浏览器中的工作方式都相同。
有谁知道为什么会出现这种差异?谢谢。
答案 0 :(得分:7)
基本上,这是因为Internet Explorer的window
对象公开了一个脚本无法覆盖的item()方法。
在行中:
item = new Object();
item
未在本地范围内声明,因此它被解释为全局对象(window.item
)的属性。在Firefox上,window
不会公开名为item
的成员,因此会引入新成员并为其分配new Object()
的结果。
另一方面,Internet Explorer公开名为window.item()
的本机方法。该成员不可写,因此无法进行任务 - 它会被默默地忽略。换句话说,item = new Object()
根本没有效果(好吧,它确实创建了一个对象,但之后无法分配它)。
id
和name
的后续分配最终会创建item()
方法的新成员。它们始终是同一方法的相同成员,因此在每次循环迭代时都会覆盖它们的值。此外,每次迭代都会将相同的对象(item()
方法)推送到数组中。
因此,数组最终包含相同对象的三倍,其id
和name
成员的值分别是分配给它们的最后一个值(在上一次迭代中){{ 1}}和3
。
答案 1 :(得分:5)
这很棘手。出于某些不明原因,Internet Explorer在全局上下文item
中有一个名为window
的本机方法(如果有人知道原因,欢迎您分享:我无法在其中找到它文件)。因此,当您使用标识符item
而不声明变量时,它会引用此方法。
循环中的第一条指令(item = new Object();
)不执行任何操作,因为window.item
是一个只读属性。因此,在此指令之后,window.item
仍然是本机函数。
下一条说明(设置id
和name
的说明)有效,因为虽然属性window.item
是只读的,但它指向的Function
对象可以修改。
在循环之后,您添加了相同的Function
对象三次,并且只有最后一次迭代计数,因为您每次都会覆盖id
和name
属性。