简体   繁体   English

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

[英]a few questions when iterator the arraylike object in javascript

In my application,I need to do some iteration with the array-like object. 在我的应用程序中,我需要对类似数组的对象进行一些迭代。

So I write a custom util method: 所以我写了一个自定义的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);
    }
  }
}

Then I meet some problems: 然后我遇到一些问题:

Suppose I have an array: var ary=[1,2,3,4,5]; 假设我有一个数组:var ary = [1,2,3,4,5];

1. how to break the loop? 1.如何打破循环?

For example, if I want to find if value '2' is included in the array,I may try this: 例如,如果我要查找数组中是否包含值“ 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. remove value of the array when iterator 2.在迭代器中删除数组的值

If I want to remove value '2' of the array,I may try this: 如果要删除数组的值“ 2”,可以尝试以下操作:

Util.forEach(ary,function(value,index){
  if(value==2){
    //delete it.
    ary.splice(i,1);
    // I wonder if this is the safe way?
  }
});

Since in java we can not do this when iterate an array,it will cause the concurrency exception. 由于在Java中,我们无法在迭代数组时执行此操作,因此会导致并发异常。

Though I run the above code without any error,but I am not sure if it is the best practice? 尽管我运行上面的代码没有任何错误,但是我不确定这是否是最佳实践吗?

Generally, you can break out from a forEach -like method by using try - catch and throw . 通常,您可以使用try - catchthrow来摆脱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;
}

The first issue can be solved by checking the return value from the callback and stopping the iteration if it returns false. 第一个问题可以通过检查回调的返回值并在返回false时停止迭代来解决。 Then you can stop the iteration by returning false from the callback. 然后,您可以通过从回调返回false来停止迭代。 Returning anything other than false (including returning nothing) will continue the iteration. 返回除false以外的任何内容(包括不返回任何内容)将继续迭代。 jQuery uses this return value technique to cancel the iteration in their .each() iterator. jQuery使用此返回值技术来取消其.each()迭代器中的迭代。 Adding that into your code, it would look like this: 将其添加到您的代码中,如下所示:

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;
            }
        }
    }
}

In the MDN documentation for forEach, you can see a sample implementation. 在forEach的MDN文档中,您可以看到一个示例实现。

On the second issue, this type of implementaation does not permit insertion or deletion of elements at or before the iteration point because that will cause some elements to get skipped in the iteration or some objects to get iterated multiple times. 在第二个问题上,这种实现方式不允许在迭代点或之前插入或删除元素,因为这将导致某些元素在迭代中被跳过或某些对象被迭代多次。 The obvious way around that would involve making a copy of the object before iterating which is not efficient when not needed. 解决该问题的明显方法是在迭代之前制作对象的副本,这在不需要时效率不高。

how to break the loop? 如何打破循环?

You're not supposed to break from forEach . 您不应该脱离forEach That's why it's called "for each", and not "for some". 这就是为什么它被称为“针对每个”而不是“针对某些”的原因。 "Breakable" JS iterators are every() (stops when the callback returns false) and some() (stops when the callback returns true). “可中断” JS迭代器分别是every() (在回调返回false时停止)和some() (在回调返回true时停止)。

Looking at your code once again it makes me think you actually want an indexOf kind of method, and not an iterator. 再次查看您的代码,使我认为您实际上需要的是indexOf类型的方法,而不是迭代器。

remove value of the array when iterator 迭代器时删除数组的值

Iterators shouldn't make any changes of the underlying array. 迭代器不应对基础数组进行任何更改。 You have to implement filter() and use it to generate a new array. 您必须实现filter()并使用它生成一个新数组。

See js iteration methods for more details. 有关更多详细信息,请参见js迭代方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM