zoukankan      html  css  js  c++  java
  • 「译」forEach循环中你不知道的3件事

    前言

    本文925字,阅读大约需要7分钟。

    总括: forEach循环中你不知道的3件事。

    自弃者扶不起,自强者击不倒。

    正文

    你觉得你真的学会用forEach了么?

    这是我之前对forEach循环的理解:就是一个普通语义化之后的for循环,可以被break,continue,return

    这篇文章将向你展示forEach中你可能不了解的3件事。

    1. return不会停止循环

    你觉得下面的代码在打印12之后会停止么?

    array = [1, 2, 3, 4];
    array.forEach(function (element) {
      console.log(element);
    
      if (element === 2) 
        return;
      
    });
    // Output: 1 2 3 4
    

    答案是不会,上述代码会正常打印1,2,3,4。如果你有Java背景,你也许会很诧异,这怎么可能呢?

    原因是我们在forEach函数中传了一个回调函数,该回调函数的行为和普通函数一样,我们return操作其实就是普通函数中return。所以并不符合我们预期将forEach循环打断。

    MDN官方文档:

    注意: 除了抛出异常以外,没有办法中止或跳出 forEach() 循环。如果你需要中止或跳出循环,forEach() 方法不是应当使用的工具。

    我们将上述代码改写:

    const array = [1, 2, 3, 4];
    const callback = function(element) {
        console.log(element);
        
        if (element === 2) 
          return; // would this make a difference? no.
    }
    for (let i = 0; i < array.length; i++) {
        callback(array[i]);
    }
    // Output: 1 2 3 4
    

    这就是上述代码实际的执行思路,return操作只作用于当前的函数,自然不会对for循环产生影响

    2. 不能break

    下面的代码你觉得会被break掉么?

    const array = [1, 2, 3, 4];
    array.forEach(function(element) {
      console.log(element);
      
      if (element === 2) 
        break;
    });
    // Output: Uncaught SyntaxError: Illegal break statement
    

    不会,甚至这行代码都不会运行,直接报错了。

    那么这段代码如何达到我们原本想达到的效果呢?

    用普通for循环就好了:

    const array = [1, 2, 3, 4];
    for (let i = 0; i < array.length; i++) {
      console.log(array[i]);
      
      if (array[i] === 2) 
        break;
    }
    // Output: 1 2
    

    3. 不能continue

    下面代码会是跳过2只打印1、3、4吗?

    const array = [1, 2, 3, 4];
    array.forEach(function (element) {
      if (element === 2) 
        continue;
      
      console.log(element);
    });
    // Output: Uncaught SyntaxError: Illegal continue statement: no surrounding iteration statement
    

    同样不会,和break一样,报错,这行代码之后甚至都不会运行。

    怎么达到预期呢?

    还是使用普通的for循环来解决:

    for (let i = 0; i < array.length; i++) {
      if (array[i] === 2) 
        continue;
      console.log(array[i]);
    }
    // Output: 1 3 4
    

    译者补充

    forEach函数的实际运行原理其实是这样的,伪代码如下:

    let arr = [1, 2];
    arr.forEach(function(ele) {
    	console.log(ele);
    }); 
    // output: 1, 2
    // 上面代码等同于
    function func(ele) {
      console.log(ele);
    }
    for (let i = 0; i < arr.length; i++) {
    	func(arr[i])
    }
    // output: 1, 2
    

    实际上forEach的polyfill实现也是这样的,在forEach函数中执行一个for循环,在for循环里调用回调函数。

    因此,像下面代码自然不会符合预期:

    let arr = [1, 2];
    let sum = 0;
    function add(a) {
    	return a;
    }
    arr.forEach(async function(ele) {
      sum += await add(ele);
    });
    console.log(sum);
    // Output:0
    

    改写如下:

    let arr = [1, 2];
    let sum = 0;
    function add(a) {
    	return a;
    }
    for (let i = 0; i < arr.length; i++) {
    	sum += await add(arr[i]);
    }
    console.log(sum);
    // Output:3
    

    订阅更多文章可关注「前端进阶学习」,回复「666」,获取一揽子前端技术书籍

    前端进阶学习

  • 相关阅读:
    使用阿里云ECS安装HDFS的小问题
    退役回忆录嘤嘤嘤
    2018 ICPC北京 H ac自动机
    Educational Codeforces Round 54 (Rated for Div. 2) DE
    sa learning
    网络流learning
    Python模块logging
    Python模块unittest
    Linux /dev/shm
    Shell 字符串操作
  • 原文地址:https://www.cnblogs.com/jztan/p/12316573.html
Copyright © 2011-2022 走看看