Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript中迭代arraylike对象时的几个问题_Javascript_Iterator - Fatal编程技术网

在javascript中迭代arraylike对象时的几个问题

在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方法:

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-with
jQuery.each()
,删除当前元素将导致跳过下一个元素。您可以在此处看到:。这是因为删除元素会导致下一个元素落入此元素所在的位置,
。each()
循环不知道您这样做了,因此它指向下一个元素,因此它永远不会获得该元素。它还将尝试超出数组的新长度。