你认为for...in和for循环有很大的区别吗?你更喜欢使用哪种“for”?为什么?
假设我们有一个关联数组的数组:
var myArray = [{'key': 'value'}, {'key': 'value1'}];
所以我们可以进行迭代:
for (var i = 0; i < myArray.length; i++)
并且:
for (var i in myArray)
我没有看到很大的差别。有性能问题吗?
你认为for...in和for循环有很大的区别吗?你更喜欢使用哪种“for”?为什么?
假设我们有一个关联数组的数组:
var myArray = [{'key': 'value'}, {'key': 'value1'}];
所以我们可以进行迭代:
for (var i = 0; i < myArray.length; i++)
并且:
for (var i in myArray)
我没有看到很大的差别。有性能问题吗?
选择应基于哪种习语被最好理解。
使用以下方式迭代数组:
for (var i = 0; i < a.length; i++)
//do stuff with a[i]
使用一个对象作为关联数组时,需要使用以下方式进行迭代:
for (var key in o)
//do stuff with o[key]
除非您有令人震惊的理由,否则请坚持使用已经建立的模式。
i < l
而不是i < a
。 - Max Nanasyfor ... in
语句会将整数转换为字符串。 - Raynal Gobel道格拉斯·克罗克福德在JavaScript: The Good Parts(第24页)中建议避免使用for in
语句。
如果您使用for in
循环遍历对象中的属性名称,则结果不会按顺序排列。更糟糕的是:您可能会得到意外的结果;它包括从原型链继承的成员和方法的名称。
除了属性之外,可以使用.hasOwnProperty
过滤掉所有内容。此代码示例执行最初想要的操作:
for (var name in obj) {
if (Object.prototype.hasOwnProperty.call(obj, name)) {
// DO STUFF
}
}
name
变量:for(var name in object)...
,否则,如果该代码位于一个函数中,name
变量最终会成为全局对象的属性(对未声明的标识符进行赋值会导致这种情况),同时在新的ECMAScript 5严格模式下,该代码将会抛出ReferenceError
。 - Christian C. SalvadójQuery 的 each(callback)
方法默认使用 for( ; ; )
循环,只有在长度为 undefined
时才会使用 for( in )
循环。
因此,在使用该函数时可以安全地假设正确的顺序。
例如:
$(['a','b','c']).each(function() {
alert(this);
});
//Outputs "a" then "b" then "c"
使用这种方法的缺点是,如果你正在进行一些非 UI 逻辑,则你的函数将不太容易移植到其他框架中。each()
函数可能最好保留在与 jQuery 选择器一起使用时,否则可能建议使用 for( ; ; )
。
不同的浏览器和循环方式会对性能产生影响。
例如:
for (var i = myArray.length-1; i >= 0; i--)
在某些浏览器上,速度几乎是下列内容的两倍:
for (var i = 0; i < myArray.length; i++)
但是,除非你的数组非常大或者你经常循环遍历它们,否则所有的数组操作都足够快。我严重怀疑数组循环是你的项目(或任何其他项目)的瓶颈。
for(var i = myArray.length; i--;)
。 - Kevin请注意,本地的Array.forEach方法现在得到了广泛的支持。
2012年的最新答案更新 所有主流浏览器--Chrome、Firefox、IE9、Safari和Opera--都支持ES5原生的array.forEach。
除非你有某些理由需要支持IE8原生(记住这些用户可以提供ES5-shim或Chrome Frame,这将提供适当的JS环境),否则使用语言本身的正确语法更加干净:
myArray.forEach(function(item, index) {
console.log(item, index);
});
使用forEach跳过原型链
仅作为对@nailer的答案的补充,使用Object.keys和forEach可以避免在不使用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]);
});
当数组稀疏时,这两者并不相同。
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.
}
我赞同选择迭代方法应该根据你的需求。我建议你不要使用for in
结构遍历原生Array
,因为它速度较慢,并且正如Chase Seibert所指出的那样,与Prototype框架不兼容。
如果你使用JavaScript,那么就有一个关于不同循环风格的优秀基准测试,你一定要看一下。不要进行早期优化,但你应该将这些东西放在脑后。
我会使用for in
获取对象的所有属性,这在调试脚本时特别有用。例如,当我探索陌生的对象时,我喜欢随手写下这行:
l = ''; for (m in obj) { l += m + ' => ' + obj[m] + '\n' } console.log(l);
它将整个对象(包括方法体)的内容转储到我的Firebug日志中。非常方便。
我做了一些事情。
相关的内容与IT技术有关。function foreach(o, f) {
for(var i = 0; i < o.length; i++) { // simple for loop
f(o[i], i); // execute a function and make the obj, objIndex available
}
}
这是使用它的方法
这适用于数组和对象(例如HTML元素列表)
foreach(o, function(obj, i) { // for each obj in o
alert(obj); // obj
alert(i); // obj index
/*
say if you were dealing with an html element may be you have a collection of divs
*/
if(typeof obj == 'object') {
obj.style.marginLeft = '20px';
}
});
我刚刚完成了这个,欢迎提出建议 :)
myArray.forEach(callback[, thisarg])
方法。 - Benji XVIif(myArray.hasOwnProperty(i)){true}
- Eric Hodonsky['foo', 'bar', 'baz'].forEach(function(element, index, array){ console.log(element, index, array); });
除了 IE8 及以下版本外,这个语法基本上可以在任何地方使用,并且它是目前最优雅的语法。 - Jon zfor...of
的语句,例如:for (let i of myArray) console.log(i);
。它可以遍历一个可迭代对象(如数组),并使用变量i
来迭代该对象中的每个元素。在循环体内部,您可以对每个元素执行任何操作。 - Vitalii Fedorenko