我被告知不要使用。。。在JavaScript中使用数组。为什么不呢?
当前回答
由于JavaScript元素保存为标准对象财产不建议使用for…遍历JavaScript数组。。。在里面循环,因为普通元素和所有可枚举的财产上市的
从…起https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections
其他回答
虽然这个问题没有特别提到,但我想补充一点,有一个很好的理由永远不要使用。。。在中使用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;正在失败。
一个重要的方面是。。。in-only迭代包含在对象中的财产,该对象的可枚举属性属性设置为true。因此,如果尝试使用for对对象进行迭代。。。然后,如果任意财产的可枚举属性为false,则可能会丢失这些属性。很有可能更改普通Array对象的可枚举属性属性,以便不枚举某些元素。虽然一般来说,属性属性倾向于应用于对象中的函数财产。
可以通过以下方式检查财产的可枚举属性属性的值:
myobject.propertyIsEnumerable('myproperty')
或获取所有四个属性属性:
Object.getOwnPropertyDescriptor(myobject,'myproperty')
这是ECMAScript 5中提供的一个特性——在早期版本中,无法更改可枚举属性属性的值(它总是设置为true)。
for/in使用两种类型的变量:哈希表(关联数组)和数组(非关联)。
JavaScript将自动确定其通过项目的方式。因此,如果您知道数组确实是非关联的,可以使用(var i=0;i<=arrayLen;i++),并跳过自动检测迭代。
但在我看来,最好使用for/in,自动检测所需的过程非常小。
对此的真正答案将取决于浏览器解析器/解释JavaScript代码的方式。它可以在浏览器之间更改。
我想不出不使用for/in的其他目的;
//Non-associative
var arr = ['a', 'b', 'c'];
for (var i in arr)
alert(arr[i]);
//Associative
var arr = {
item1 : 'a',
item2 : 'b',
item3 : 'c'
};
for (var i in arr)
alert(arr[i]);
除了其他答案中给出的原因外,如果需要计算计数器变量,您可能不想使用“for…In”结构,因为循环会迭代对象财产的名称,因此该变量是一个字符串。
例如
for (var i=0; i<a.length; i++) {
document.write(i + ', ' + typeof i + ', ' + i+1);
}
将写入
0, number, 1
1, number, 2
...
鉴于
for (var ii in a) {
document.write(i + ', ' + typeof i + ', ' + i+1);
}
将写入
0, string, 01
1, string, 11
...
当然,这可以通过包括
ii = parseInt(ii);
但第一种结构更直接。
TL&DR:在数组中使用for in循环并不是坏事,事实上恰恰相反。
我认为如果在数组中正确使用,for in循环是JS的瑰宝。你应该完全控制你的软件,并知道你在做什么。让我们看看上面提到的缺点,并逐一反驳它们。
它还遍历继承的财产:首先,对Array.prototype的任何扩展都应该使用Object.defineProperty()完成,并且它们的可枚举描述符应该设置为false。任何没有这样做的库都不应该被使用。添加到继承链中的财产稍后会被计数:当按Object.setPrototypeOf或按类扩展进行数组子分类时。您应该再次使用Object.defineProperty(),它默认将可写、可枚举和可配置的属性描述符设置为false。让我们在这里看到一个数组子类示例。。。
函数堆栈(…a){var stack=新数组(…a);Object.setPrototypeOf(堆栈,stack.prototype);返回堆栈;}Stack.prototype=对象.create(Array.prototype);//现在堆栈可以完全访问数组方法。Object.defineProperty(Stack.prototype,“constructor”,{value:Stack});//现在Stack是一个合适的构造函数Object.defineProperty(Stack.prototype,“peak”,{value:function(){//将Stack“only”方法添加到Stack.prototype。返回this[this.length-1];}});var s=新堆栈(1,2,3,4,1);console.log(s.peak());s[s.length]=7;console.log(“长度:”,s.length);s.push(42);console.log(JSON.stringify);console.log(“长度:”,s.length);for(var i in s)console.log(s[i]);
所以你看。。因为您关心代码,所以in循环现在是安全的。
for in循环很慢:见鬼,没有。如果你在不时需要的稀疏数组上循环,这是迄今为止最快的迭代方法。这是人们应该知道的最重要的表演技巧之一。让我们看一个例子。我们将在稀疏数组上循环。
变量a=[];a[0]=“零”;a[10000000]=“1000万”;console.time(“用于数组a上的循环:”);对于(var i=0;i<a.length;i++)a[i]&&console.log(a[i]);console.timeEnd(“用于数组a上的循环:”);console.time(“用于数组a上的循环:”);对于(a中的var i)a[i]&&console.log(a[i]);console.timeEnd(“用于数组a上的循环中:”);