我被告知不要使用。。。在JavaScript中使用数组。为什么不呢?
当前回答
的问题。。。在…-只有当程序员不真正理解语言时,这才成为问题;它实际上不是一个bug或任何东西,而是它迭代对象的所有成员(好吧,所有可枚举成员,但这只是一个细节)。当您只想迭代数组的索引财产时,确保语义一致的唯一方法是使用整数索引(即for(vari=0;i<array.length;++i)样式循环)。
任何对象都可以有与之关联的任意财产。特别是将附加财产加载到数组实例上并没有什么可怕的。如果代码只想看到索引的类似数组的财产,则必须坚持使用整数索引。完全了解用于…的代码。。。在does和really需要查看所有财产,那么这也没关系。
其他回答
for in循环在遍历数组时将索引转换为字符串。例如,在下面的代码中,在用i+1初始化j的第二个循环中,i是索引,但在字符串(“0”、“1”等)中,js中的number+string是字符串。如果js遇到“0”+1,则返回“01”。
var maxProfit=函数(价格){设maxProfit=0;for(让我输入价格){for(设j=i+1;j<prices.length;j++){console.log(价格[j]-价格[i],“i,j”,i,j,类型i,类型j);如果((prices[j]-prices[i])>maxProfit)maxProfit=(prices[j]-prices[i]);}}return maxProfit;};最大利润([7,1,5,3,6,4]);
因为它通过对象字段而不是索引枚举。你可以用索引“length”获得值,我怀疑你是否想要这个。
虽然这个问题没有特别提到,但我想补充一点,有一个很好的理由永远不要使用。。。在中使用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;正在失败。
主要有两个原因:
One
就像其他人所说的那样,您可能会得到不在数组中或从原型继承的密钥。因此,假设库向Array或Object原型添加了一个属性:
Array.prototype.someProperty = true
您可以将其作为每个阵列的一部分:
for(var item in [1,2,3]){
console.log(item) // will log 1,2,3 but also "someProperty"
}
可以使用hasOwnProperty方法解决此问题:
var ary = [1,2,3];
for(var item in ary){
if(ary.hasOwnProperty(item)){
console.log(item) // will log only 1,2,3
}
}
但这对于使用for in循环迭代任何对象都是正确的。
Two
通常,数组中项目的顺序很重要,但for in循环不一定以正确的顺序迭代,这是因为它将数组视为对象,这是在JS中实现的方式,而不是数组。这看起来是一件小事,但它确实会破坏应用程序,而且很难调试。
简短的回答:这不值得。
更长的答案:即使不需要顺序元素顺序和最佳性能,这也不值得。
长篇大论:这不值得。。。
使用for(数组中的var属性)将导致数组作为对象迭代,遍历对象原型链,最终执行速度比基于索引的for循环慢。for(…in…)不能保证按顺序返回对象财产,这可能是意料之中的。使用hasOwnProperty()和!用于筛选对象财产的isNaN()检查是一项额外的开销,导致它的执行速度更慢,并否定了首先使用它的主要原因,即因为它的格式更简洁。
出于这些原因,甚至不存在性能和便利性之间可接受的权衡。除非目的是将数组作为对象处理,并对数组的对象财产执行操作,否则实际上没有任何好处。