您是否认为for ... in和for循环有很大的不同?您更喜欢使用哪种“用于”,为什么?
假设我们有一个关联数组的数组:
var myArray = [{'key': 'value'}, {'key': 'value1'}];
这样我们就可以迭代:
for (var i = 0; i < myArray.length; i++)
和:
for (var i in myArray)
我没什么大不同。有性能问题吗?
您是否认为for ... in和for循环有很大的不同?您更喜欢使用哪种“用于”,为什么?
假设我们有一个关联数组的数组:
var myArray = [{'key': 'value'}, {'key': 'value1'}];
这样我们就可以迭代:
for (var i = 0; i < myArray.length; i++)
和:
for (var i in myArray)
我没什么大不同。有性能问题吗?
两者之间有重要区别。for-in遍历对象的属性,因此当case是数组时,它将不仅遍历其元素,而且遍历其具有的“ remove”功能。
for (var i = 0; i < myArray.length; i++) {
console.log(i)
}
//Output
0
1
for (var i in myArray) {
console.log(i)
}
// Output
0
1
remove
您可以将for-in与一起使用if(myArray.hasOwnProperty(i))
。尽管如此,当遍历数组时,我总是更喜欢避免这种情况,而只使用for(;;)语句。
尽管它们都非常相似,但还是有细微的差别:
var array = ["a", "b", "c"];
array["abc"] = 123;
console.log("Standard for loop:");
for (var index = 0; index < array.length; index++)
{
console.log(" array[" + index + "] = " + array[index]); //Standard for loop
}
在这种情况下,输出为:
循环标准:
数组[0] = A
阵列[1] = B
数组[2] = C
console.log("For-in loop:");
for (var key in array)
{
console.log(" array[" + key + "] = " + array[key]); //For-in loop output
}
而在这种情况下,输出为:
转入圈:
阵列[1] = B
数组[2] = C
阵列[10] = D
数组[ABC] = 123
使用Array()。forEach循环利用并行性
根据jsperf,较短和最佳的代码是
keys = Object.keys(obj);
for (var i = keys.length; i--;){
value = obj[keys[i]];// or other action
}
for(;;)用于数组:[20,55,33]
for..in是对象:{x:20,y:55:z:33}
我已经看到使用对象,原型和数组的“ for each”问题
我的理解是for for是对象的属性,而不是数组的属性
如果您真的想加速代码,那该怎么办?
for( var i=0,j=null; j=array[i++]; foo(j) );
这有点在for语句中包含while逻辑,并且冗余程度较低。Firefox也具有Array.forEach和Array.filter
数组上的for in循环与Prototype不兼容。如果您认为将来可能需要使用该库,则最好坚持使用for循环。
小心!
例如,如果您有多个脚本标签,并且正在标签属性中搜索信息,则必须将.length属性与for循环一起使用,因为它不是一个简单的数组,而是一个HTMLCollection对象。
https://developer.mozilla.org/en/DOM/HTMLCollection
如果将foreach语句用于(list中的var i),它将在大多数浏览器中返回HTMLCollection的属性和方法!
var scriptTags = document.getElementsByTagName("script");
for(var i = 0; i < scriptTags.length; i++)
alert(i); // Will print all your elements index (you can get src attribute value using scriptTags[i].attributes[0].value)
for(var i in scriptTags)
alert(i); // Will print "length", "item" and "namedItem" in addition to your elements!
即使getElementsByTagName应该返回NodeList,大多数浏览器也会返回HTMLCollection:https : //developer.mozilla.org/en/DOM/document.getElementsByTagName
我会根据想要引用项目的方式使用不同的方法。
如果只需要当前项目,请使用foreach。
如果需要索引器进行相对比较,则用于。(即与上一个/下一个项目相比如何?)
我从未注意到性能差异。我会等到出现性能问题后再担心它。
使用for(myArray中的var i),您也可以循环对象,我将包含键名,并且可以通过myArray [i]访问该属性。另外,您将添加到对象中的任何方法也将包含在循环中,即,如果您使用任何外部框架(如jQuery或原型),或者如果直接将方法添加到对象原型,则我将指向这些方法。
使用forEach跳过原型链
只是上述@nailer答案的快速附录,将forEach与Object.keys一起使用意味着您可以避免在原型链上进行迭代,而不必使用hasOwnProperty。
var Base = function () {
this.coming = "hey";
};
var Sub = function () {
this.leaving = "bye";
};
Sub.prototype = new Base();
var tst = new Sub();
for (var i in tst) {
console.log(tst.hasOwnProperty(i) + i + tst[i]);
}
Object.keys(tst).forEach(function (val) {
console.log(val + tst[val]);
});
Douglas Crockford建议在JavaScript:The Good Parts(第24页)中避免使用该for in
语句。
If you use for in
to loop over property names in an object, the results are not ordered. Worse: You might get unexpected results; it includes members inherited from the prototype chain and the name of methods.
Everything but the properties can be filtered out with .hasOwnProperty
. This code sample does what you probably wanted originally:
for (var name in obj) {
if (Object.prototype.hasOwnProperty.call(obj, name)) {
// DO STUFF
}
}
数组稀疏时,两者不相同。
var array = [0, 1, 2, , , 5];
for (var k in array) {
// Not guaranteed by the language spec to iterate in order.
alert(k); // Outputs 0, 1, 2, 5.
// Behavior when loop body adds to the array is unclear.
}
for (var i = 0; i < array.length; ++i) {
// Iterates in order.
// i is a number, not a string.
alert(i); // Outputs 0, 1, 2, 3, 4, 5
// Behavior when loop body modifies array is clearer.
}
所有主要浏览器的2012当前版本的更新答案 -Chrome,Firefox,IE9,Safari和Opera支持ES5的本机array.forEach。
除非您有某些本机支持IE8的理由(请记住可以为这些用户提供ES5-shim或Chrome框架,这将提供适当的JS环境),否则使用该语言的适当语法会更干净:
myArray.forEach(function(item, index) {
console.log(item, index);
});
请注意,本机Array.forEach方法现已得到广泛支持。
该选择应基于对哪种习语最了解。
使用以下方法迭代数组:
for (var i = 0; i < a.length; i++)
//do stuff with a[i]
使用以下方法来迭代用作关联数组的对象:
for (var key in o)
//do stuff with o[key]
除非您有惊天动地的理由,否则请遵循既定的使用模式。
根据使用哪种循环以及使用哪种浏览器,性能会有差异。
例如:
for (var i = myArray.length-1; i >= 0; i--)
在某些浏览器中的速度几乎是:
for (var i = 0; i < myArray.length; i++)
但是,除非您的数组很大,否则您必须不断地循环它们,否则它们的速度都足够快。我严重怀疑数组循环是否会成为您项目中的瓶颈(或任何其他与此项目有关的项目)
for in语句允许遍历对象的所有属性的名称。不幸的是,它还会遍历通过原型链继承的所有成员。当关注数据成员时,这不利于提供方法功能。