【问题标题】:return statement in forEach won't stop execution of function [duplicate]forEach 中的 return 语句不会停止函数的执行 [重复]
【发布时间】:2014-09-17 02:16:19
【问题描述】:

我正在尝试确定一个数组是否包含某个项目。如果是,我想保留该功能,否则应该添加它。

function addPacking(item){

    data.packings.forEach(function(entry){
       if(item.name == entry.name){
           return;
       }
    });

    data.packings.push(item);

}

不幸的是,即使满足 if 条件,也会推送数据。如何在不使用 else 条件的情况下防止这种行为?

(我不想使用else,因为我的实际代码比这复杂得多,我想让它保持可读性)

编辑:

forEach 是否异步执行?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    老问题,但以防其他人遇到此线程。

    如果你使用 ECMAScript 6,你可以使用 Array find() 方法

    var found = myArray.find(function (element) { return element === arrayToFind; });
    

    所以对于这个特定的场景将是:

    function addPacking(item){
        var foundItem = data.find(function(entry){ return entry.name == item.name});
        if (foundItem) data.packings.push(foundItem);    
    }
    

    请参阅http://www.w3schools.com/jsref/jsref_find.asp 了解另一个工作示例。

    【讨论】:

      【解决方案2】:

      你只是从子函数返回,而不是从父函数返回

      function addPacking(item){
          var check=false;
          data.packings.forEach(function(entry){
             if(item.name == entry.name){
                check=true; 
                return;
             }
          });
           if (check) return;
          data.packings.push(item);
      
      }
      

      【讨论】:

      • 这会起作用,但即使找到匹配项,它仍然会循环遍历所有项目,并且循环内的return 毫无意义。
      【解决方案3】:

      除了抛出异常 (@Yoshi) 之外,您无法停止 forEach 的执行。不应将其视为影响程序代码流的选项(@Me)。

      你可以做的是使用另一种方法someevery

      function addPacking(item){
          var contains = data.packings.every(function(entry){
             return item.name != entry.name;
          });
      
          if(contains) {
             data.packings.push(item);
          }
      }
      

      或者

      function addPacking(item){
          var conatins = !data.packings.some(function(entry){
             return item.name == entry.name;
          });
      
          if(contains) { 
             data.packings.push(item);
          }
      }
      

      【讨论】:

      • @epipav:forEach方法是一种方法,与foreach结构不同。
      • @epipav Wat?! “注意:没有办法停止或中断 forEach 循环。解决方案是使用 Array.every 或 Array.some。请参见下面的示例。”
      • 使用everysome 会起作用,但是使用&& 运算符的副作用而不是if 语句并不能使它非常可读。
      • 学究式:You can't stop forEach 不正确。
      • @Yoshi 我怀疑抛出异常应该由学究气的程序员考虑。 :)
      【解决方案4】:

      老办法有时是最好的。这是因为您在调用.forEach 时传递了一个委托函数。代表中的return 正在丢失,并且不适用于任何东西。为了得到你想要的结果,你需要退出调用函数addPacking。这可以使用简单的for 循环来完成。

      function addPacking(item){
          for (var i = 0; i < data.packings.length++; i++) {
              if (item.name == data.packings[i].name) {
                  return;
              }
          }
      
          data.packings.push(item);
      });
      

      这种方法还支持旧版浏览器,不像someeveryforEach

      【讨论】:

      • 它可以工作,但数组也可能包含未定义的(当然这对于 OP 情况可能不是问题)。
      • 那是正确的阿德里亚诺,我只是根据提供的条件来确定我的条件。 :)
      • 我发现这是最方便的选择,感谢您和其他所有人提供这么多不同的方法和解释!
      • 成功了。谢谢 :)。我们也可以这样试试 ** function addPacking(item){ for (let record of data.packings) { if (item.name == record.name) { return; } } data.packings.push(item); }); **
      【解决方案5】:

      返回只是中止在forEach 中调用的函数,而不是你的addPackings 函数。

      function addPacking(item){
          var isInPackings = false;
          data.packings.forEach(function(entry){
             if(item.name == entry.name){
                 isInPackings = true;
             }
          });
          if (!isInPackings)
              data.packings.push(item);
      
      }
      

      【讨论】:

        猜你喜欢
        • 2019-08-12
        • 1970-01-01
        • 2014-04-05
        • 1970-01-01
        • 2020-01-18
        • 2021-09-10
        • 1970-01-01
        • 1970-01-01
        • 2022-01-24
        相关资源
        最近更新 更多