在javascript中迭代arraylike对象时的几个问题
在我的应用程序中,我需要使用类似数组的对象进行一些迭代 因此,我编写了一个自定义的util方法:在javascript中迭代arraylike对象时的几个问题,javascript,iterator,Javascript,Iterator,在我的应用程序中,我需要使用类似数组的对象进行一些迭代 因此,我编写了一个自定义的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,
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);
}
}
}
2。使用迭代器时删除数组的值
如果要删除数组的值“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.
}
});
Util.forEach(ary,function(value,index){
if(value==2){
//delete it.
ary.splice(i,1);
// I wonder if this is the safe way?
}
});
因为在java中,我们在迭代数组时不能这样做,这将导致并发异常
虽然我运行上述代码时没有任何错误,但我不确定这是否是最佳做法?第一个问题可以通过检查回调返回值并在返回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;
}
}
}
}
Util.forEach=函数(迭代器、回调、上下文){
if(iterator.length&&callback){
for(var i=0;i
在for forEach中,您可以看到一个示例实现
在第二个问题上,这种类型的实现不允许在迭代点或之前插入或删除元素,因为这将导致某些元素在迭代中被跳过,或者某些对象被迭代多次。显而易见的解决方法是在迭代之前复制对象,这在不需要时是无效的。通常,您可以通过使用
try
-catch
和throw
来打破类似的方法
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;
}
var值='未找到';
试一试{
Util.forEach(数组、函数(值、索引){
如果(值==2){
投掷值//
如何打破循环
您不应该从forEach
中断。这就是为什么它被称为“for each”,而不是“for some”。“Breakable”JS迭代器是each()
(回调返回false时停止)和some()
(回调返回true时停止)
再看一遍你的代码,我觉得你实际上想要一种indexOf
方法,而不是迭代器
在使用迭代器时删除数组的值
迭代器不应该对基础数组进行任何更改。您必须实现filter()
,并使用它生成新数组
有关更多详细信息,请参阅。如果您仔细查看,您会发现OP使用的不是数组.prototype.forEach
,而是一种自定义的Util.forEach
方法。谢谢您的回复。对于第二个问题,正如您所说,复制效率不高,所以还有其他选择吗?@hguser-您不能既吃蛋糕又吃蛋糕。您也可以制作数组的副本,这样对原始数组的更改就不会影响每个元素的迭代。或者,对于哪些类型的修改是可以的,哪些类型不可以,您遵循一系列规则。选择一个或另一个。例如,更改任何元素都可以。甚至在当前元素之后添加或删除任何元素都可以。这只是在当前元素之前或包含当前元素之前添加/删除元素不确定。@hguser-如果要在当前元素之前添加/删除元素,请为
循环编写一个,而不是使用。each(fn)
当您根据特定情况下希望发生的情况修改数组时,您可以手动控制迭代索引发生的情况。那么,这是否意味着我可以修改我的代码?因为我“删除当前元素”。@hguser-withjQuery.each()
,删除当前元素将导致跳过下一个元素。您可以在此处看到:。这是因为删除元素会导致下一个元素落入此元素所在的位置,。each()
循环不知道您这样做了,因此它指向下一个元素,因此它永远不会获得该元素。它还将尝试超出数组的新长度。