zoukankan      html  css  js  c++  java
  • JavaScript中如何中断forEach循环

    先来看下forEach的实现

    // Production steps of ECMA-262, Edition 5, 15.4.4.18
    // Reference: http://es5.github.io/#x15.4.4.18
    if (!Array.prototype.forEach) {

      Array.prototype.forEach = function(callback, thisArg) {

        var T, k;

        if (this === null) {
          throw new TypeError(' this is null or not defined');
        }

        // 1. Let O be the result of calling toObject() passing the
        // |this| value as the argument.
        var O = Object(this);

        // 2. Let lenValue be the result of calling the Get() internal
        // method of O with the argument "length".
        // 3. Let len be toUint32(lenValue).
        var len = O.length >>> 0;

        // 4. If isCallable(callback) is false, throw a TypeError exception.
        // See: http://es5.github.com/#x9.11
        if (typeof callback !== "function") {
          throw new TypeError(callback + ' is not a function');
        }

        // 5. If thisArg was supplied, let T be thisArg; else let
        // T be undefined.
        if (arguments.length > 1) {
          T = thisArg;
        }

        // 6. Let k be 0
        k = 0;

        // 7. Repeat, while k < len
        while (k < len) {

          var kValue;

          // a. Let Pk be ToString(k).
          //    This is implicit for LHS operands of the in operator
          // b. Let kPresent be the result of calling the HasProperty
          //    internal method of O with argument Pk.
          //    This step can be combined with c
          // c. If kPresent is true, then
          if (k in O) {

            // i. Let kValue be the result of calling the Get internal
            // method of O with argument Pk.
            kValue = O[k];

            // ii. Call the Call internal method of callback with T as
            // the this value and argument list containing kValue, k, and O.
            callback.call(T, kValue, k, O);
          }
          // d. Increase k by 1.
          k++;
        }
        // 8. return undefined
      };
    }

    基本用法:

    arr.forEach(callback[, thisArg]),callback会接收到三个参数:currentValue、index、array
    var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];

    ary.forEach(function(value, index, _ary) {
        console.log(index + ": " + value);
        return false;
    });

    // logs:

    0: JavaScript
    1: Java
    2: CoffeeScript
    3: TypeScript

     

    使用some函数

    var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];

    ary.some(function (value, index, _ary) {
        console.log(index + ": " + value);
        return value === "CoffeeScript";
    });

    // logs:

    0: JavaScript
    1: Java
    2: CoffeeScript

     

    使用every函数

    var ary = ["JavaScript", "Java", "CoffeeScript", "TypeScript"];

    ary.every(function(value, index, _ary) {
        console.log(index + ": " + value);
        return value.indexOf("Script") > -1;
    });

    // logs:

    0: JavaScript
    1: Java

    使用fo..of

    let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    for (let el of arr) {
      console.log(el);
      if (el === 5) {
        break;
      }
    }
    // logs:
    0
    1
    2
    3
    4
    5

     

    而如果forEach想实现类似every、some函数的效果该如何做呢?

    在stackoverflow上得票比较高的有如下几类方法 :

    1、循环外使用try.. catch,当需要中断时throw 一个异常,然后catch进行捕获;

    2、重写forEach(也是借鉴第一种方法);

    var BreakException = {};

    try {
      [1, 2, 3].forEach(function(el) {
        console.log(el);
        if (el === 2) throw BreakException;
      });
    } catch (e) {
      if (e !== BreakException) throw e;
    }
     
    // Use a closure to prevent the global namespace from be polluted.
    (function() {
      // Define StopIteration as part of the global scope if it
      // isn't already defined.
      if(typeof StopIteration == "undefined") {
        StopIteration = new Error("StopIteration");
      }

      // The original version of Array.prototype.forEach.
      var oldForEach = Array.prototype.forEach;

      // If forEach actually exists, define forEach so you can
      // break out of it by throwing StopIteration.  Allow
      // other errors will be thrown as normal.
      if(oldForEach) {
        Array.prototype.forEach = function() {
          try {
            oldForEach.apply(this, [].slice.call(arguments, 0));
          }
          catch(e) {
            if(e !== StopIteration) {
              throw e;
            }
          }
        };
      }
    })();
     
     
    // Show the contents until you get to "2".
    [0,1,2,3,4].forEach(function(val) {
      if(val == 2)
        throw StopIteration;
      alert(val);
    });

     

    参考链接:

    http://dean.edwards.name/weblog/2006/07/enum/

    http://www.jsnoob.com/2013/11/26/how-to-break-the-foreach/

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of


  • 相关阅读:
    WCF Security基本概念(转载)
    Step by Step 配置使用HTTPS的ASP.NET Web应用
    HTTPS那些事(三)攻击实例与防御(转载)
    HTTPS那些事(二)SSL证书(转载)
    HTTPS那些事(一)HTTPS原理(转载)
    WCF服务创建与抛出强类型SOAP Fault
    WCF服务的异常消息
    如何创建一个RESTful WCF Service
    (转)webHttpBinding、basicHttpBinding和wsHttpBinding区别
    如何创建一个AJAX-Enabled WCF Service
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/5924581.html
Copyright © 2011-2022 走看看