在我的应用程序中,我需要使用类似数组的对象进行一些迭代。
所以我写了一个自定义的util方法:
Util.forEach=function(iterator,callback,context){
if(iterator.length){
for(var i=0;i<iterator.length;i++){
var val=iterator[i];
callback && callback.call(context||null,val,i);
}
}
}
然后我遇到了一些问题:
假设我有一个数组:var ary = [1,2,3,4,5];
1。如何打破循环?
例如,如果我想查找数组中是否包含值'2',我可以试试这个:
Util.forEach(ary,function(value,index){
if(value==2){
//find mached value,now I should break and return this value.
//but I can not use 'break' in this context.
}
});
2。迭代器
时删除数组的值如果我想删除数组的值'2',我可以试试这个:
Util.forEach(ary,function(value,index){
if(value==2){
//delete it.
ary.splice(i,1);
// I wonder if this is the safe way?
}
});
因为在java中我们在迭代数组时不能这样做,所以会导致并发异常。
虽然我没有任何错误地运行上面的代码,但我不确定它是否是最好的做法?
答案 0 :(得分:1)
通常,您可以使用try
- catch
和throw
从类似forEach
的方法中脱颖而出。
var value = 'Not Found';
try {
Util.forEach(ary, function(value, index) {
if(value == 2) {
throw value; //<-- Throw the found result: Terminates current forEach
}
});
} catch (found) { // Catch the thrown result
value = found;
}
答案 1 :(得分:0)
第一个问题可以通过检查回调的返回值并在迭代返回false时停止迭代来解决。然后,您可以通过从回调中返回false
来停止迭代。返回false
以外的任何内容(包括不返回任何内容)将继续迭代。 jQuery使用此返回值技术取消其.each()
迭代器中的迭代。将其添加到您的代码中,它将如下所示:
Util.forEach=function(iterator,callback,context){
if (iterator.length && callback) {
for(var i = 0; i < iterator.length; i++){
var val=iterator[i];
if (callback.call(context||window,val,i) === false) {
break;
}
}
}
}
在MDN documentation for forEach中,您可以看到示例实现。
在第二个问题上,这种类型的实现不允许在迭代点处或之前插入或删除元素,因为这会导致某些元素在迭代中被跳过或者某些对象被多次迭代。显而易见的方法是在迭代之前制作对象的副本,这在不需要时效率不高。
答案 2 :(得分:0)
如何打破循环?
你不应该与forEach
分手。这就是为什么它被称为“为每个人”,而不是“为某些人”。 “可破坏的”JS迭代器是every()
(当回调返回false时停止)和some()
(当回调返回true时停止)。
再一次查看你的代码,我觉得你真的想要一种indexOf
种方法,而不是迭代器。
在迭代器
时删除数组的值
迭代器不应对底层数组进行任何更改。您必须实现filter()
并使用它来生成新数组。
有关详细信息,请参阅js iteration methods。