你认为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]
除非你有惊天动地的原因,否则坚持既定的使用模式.
Douglas Crockford建议使用JavaScript:好的部分(第24页)以避免使用该for in
语句.
如果您使用for in
循环对象中的属性名称,则不会对结果进行排序.更糟糕:你可能会得到意想不到的结果; 它包括从原型链继承的成员和方法的名称.
除了属性之外的所有东西都可以过滤掉.hasOwnProperty
.此代码示例执行您最初可能需要的内容:
for (var name in obj) { if (Object.prototype.hasOwnProperty.call(obj, name)) { // DO STUFF } }
jQuery的each(callback)
方法for( ; ; )
默认使用循环,并且for( in )
仅在长度为时才使用undefined
.
因此,我会说使用此功能时可以安全地假设正确的顺序.
示例:
$(['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++)
但是,除非你的阵列是巨大的,否则你不断循环它们都足够快.我严重怀疑阵列循环是你项目的瓶颈(或者对于那个问题的任何其他项目)
请注意,现在广泛支持本机Array.forEach方法.
更新了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()的完整文档位于MDN.
我的第二个意见是你应该根据你的需要选择迭代方法.我建议你其实并没有到过遍历本地Array
与for in
结构.这是方法要慢和,大通塞伯特指着刚才,不与原型框架相兼容.
对于不同的循环样式有一个很好的基准,如果你使用JavaScript,你绝对应该看一看.不要做早期优化,但是你应该把这些东西放在脑后的某个地方.
我将使用for in
获取对象的所有属性,这在调试脚本时特别有用.例如,当我探索不熟悉的对象时,我喜欢使用这条线:
l = ''; for (m in obj) { l += m + ' => ' + obj[m] + '\n' } console.log(l);
它将整个对象的内容(与方法体一起)转储到我的Firebug日志中.非常方便.
当数组稀疏时,两者不一样.
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. }
使用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]); });
这是我做的事情.
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'; } });
我刚刚做了这个,所以我愿意接受建议:)
我会根据我想引用这些项目的方式使用不同的方法.
如果您只想要当前项目,请使用foreach.
如果您需要索引器进行相对比较,请使用此选项.(即这与上一个/下一个项目相比如何?)
我从未注意到性能差异.我会等到遇到性能问题然后再担心它.