我被告知不要使用。。。在JavaScript中使用数组。为什么不呢?


当前回答

的问题。。。在…-只有当程序员不真正理解语言时,这才成为问题;它实际上不是一个bug或任何东西,而是它迭代对象的所有成员(好吧,所有可枚举成员,但这只是一个细节)。当您只想迭代数组的索引财产时,确保语义一致的唯一方法是使用整数索引(即for(vari=0;i<array.length;++i)样式循环)。

任何对象都可以有与之关联的任意财产。特别是将附加财产加载到数组实例上并没有什么可怕的。如果代码只想看到索引的类似数组的财产,则必须坚持使用整数索引。完全了解用于…的代码。。。在does和really需要查看所有财产,那么这也没关系。

其他回答

因为。。。in通过持有数组的对象枚举,而不是数组本身。如果我向数组原型链中添加了一个函数,那么它也将包含在内。即。

Array.prototype.myOwnFunction = function() { alert(this); }
a = new Array();
a[0] = 'foo';
a[1] = 'bar';
for(x in a){
 document.write(x + ' = ' + a[x]);
}

这将写入:

0 = foo
1 = bar
myOwnFunction = function() { alert(this); }

而且,由于您永远无法确定不会向原型链中添加任何内容,因此只需使用for循环来枚举数组:

for(i=0,x=a.length;i<x;i++){
 document.write(i + ' = ' + a[i]);
}

这将写入:

0 = foo
1 = bar

原因是一个构造:

变量a=[];//创建新的空数组。a[5]=5;//调整数组大小的完全合法的JavaScript。对于(var i=0;i<a.length;i++){//按照每个人的预期,在从0到5的数字索引上重复。控制台日志(a[i]);}/*将显示:未定义未定义未定义未定义未定义5.*/

有时可能完全不同:

变量a=[];a[5]=5;for(a中的var x){//仅显示显式设置的索引“5”,并忽略0-4console.log(x);}/*将显示:5.*/

还要考虑JavaScript库可能会这样做,这会影响您创建的任何数组:

//在JavaScript库的深处。。。Array.prototype.foo=1;//现在你不知道下面的代码会做什么。变量a=[1,2,3,4,5];for(a中的var x){//现在foo是每个数组的一部分//将在此处显示为“x”值。console.log(x);}/*将显示:01.2.3.4.食品*/

的问题。。。在…-只有当程序员不真正理解语言时,这才成为问题;它实际上不是一个bug或任何东西,而是它迭代对象的所有成员(好吧,所有可枚举成员,但这只是一个细节)。当您只想迭代数组的索引财产时,确保语义一致的唯一方法是使用整数索引(即for(vari=0;i<array.length;++i)样式循环)。

任何对象都可以有与之关联的任意财产。特别是将附加财产加载到数组实例上并没有什么可怕的。如果代码只想看到索引的类似数组的财产,则必须坚持使用整数索引。完全了解用于…的代码。。。在does和really需要查看所有财产,那么这也没关系。

虽然这个问题没有特别提到,但我想补充一点,有一个很好的理由永远不要使用。。。在中使用NodeList(就像从querySelectorAll调用中获得的那样,因为它根本看不到返回的元素,而只在NodeListneneneba属性上迭代。

在单个结果的情况下,我得到:

var nodes = document.querySelectorAll(selector);
nodes
▶ NodeList [a._19eb]
for (node in nodes) {console.log(node)};
VM505:1 0
VM505:1 length
VM505:1 item
VM505:1 entries
VM505:1 forEach
VM505:1 keys
VM505:1 values

这解释了为什么我的for(节点中的节点)node.href=newLink;正在失败。

因为它通过对象字段而不是索引枚举。你可以用索引“length”获得值,我怀疑你是否想要这个。