zoukankan      html  css  js  c++  java
  • Js中foreach()用法及使用的坑

    foreach 语法:

    [ ].forEach(function(value,index,array){
      //code something
    });

    forEach()方法对数组的每个元素执行一次提供的函数。

    var array = ['a', 'b', 'c'];
    array.forEach(function(element) {
    console.log(element);
    });

    输出为:

    a;
    b;
    c;

    forEach()方法对数组的每个元素执行一次提供的函数。总是返回undefined;

    var arr = [1,2,3,4];   
    arr.forEach(alert);

    //等价于:
    var arr = [1, 2, 3, 4];
    for (var k = 0, length = arr.length; k < length; k++) {
    alert(array[k]);
    }

    forEach方法中的function回调有三个参数:
    第一个参数是遍历的数组内容,
    第二个参数是对应的数组索引,
    第三个参数是数组本身

    forEach使用的坑

    1.forEach不支持break

    大家都知道,在使用for循环时可以使用break跳出循环,比如我希望找到数组中符合条件的第一个元素就跳出循环,这对于优化数组遍历是非常棒的。很遗憾,forEach并不支持break操作,使用break会导致报错。

    let arr = [1, 2, 3, 4],
        i = 0,
        length = arr.length;
    for (; i < length; i++) {
        console.log(arr[i]); //1,2
        if (arr[i] === 2) {
            break;
        };
    };
    
    arr.forEach((self,index) => {
        console.log(self);
        if (self === 2) {
            break; //报错
        };
    });

    那forEach能不能跳出循环呢?可以,不过不是使用break,而是结合try catch操作

    2.forEach中使用return无效

    首先需要确定的,直接再for循环中使用return会报错(函数中使用for可以return),forEach中使用return不会报错,但rerutn并不会生效,我们来看个例子:

    let arr = [1, 2, 3, 4];
    
    function find(array, num) {
        array.forEach((self, index) => {
            if (self === num) {
                return index;
            };
        });
    };
    let index = find(arr, 2);// undefined

    上述代码想要找到数字2在数组中的索引,但return并不会起到终止代码运行并返回值的作用。

    当然如果我们真的要用return返回某个值,那就只能将return操作放在函数中,而不是forEach循环中,像这样:

    function find(array, num) {
        let _index;
        array.forEach((self, index) => {
            if (self === num) {
                _index = index;
            };
        });
        return _index;
    };

    3.forEach删除自身元素index不会被重置

    还记得文章开头的问题吗,那段代码其实只会执行一次,数组也不会被删除干净,这是因为forEach在遍历跑完回调函数后,会隐性让index自增,像这样:

    arr.forEach((item, index) => {
        arr.splice(index, 1);
        console.log(1);
        //这里隐性让index自增加1
        index++;
    });

    当第一次遍历结束,此时数组为[2]而index变成了1,此时数组最大索引只是0,不满足条件,所以跳出了循环。

    灵机一动,有没有什么办法让此时的forEach不跳出循环呢,当然有,使用ES6的拓展运算符。

    [...arr].forEach((item, index) => {
        arr.splice(index, 1);
        console.log(1);
    });

    通过拓展运算符重置数组arr,达到不跳出循环的目的,你会发现内部确实执行了两次,很遗憾的是index依旧没被重置,所以数组arr还是无法在遍历的同时删空自己。

    因为在实际开发中,遍历数组同时删除某项的操作十分常见,所以对于习惯了forEach的同学,这一点一定要注意。

     

    for与forEach的区别

    那么说到这里,for循环与forEach有什么区别呢?我想大家应该都能说上几点了吧,比如:

    1.for循环可以使用break跳出循环,但forEach不能。

    2.for循环可以控制循环起点(i初始化的数字决定循环的起点),forEach只能默认从索引0开始。

    3.for循环过程中支持修改索引(修改 i),但forEach做不到(底层控制index自增,我们无法左右它)。

    http://www.bijianshuo.com 软文发稿平台

    数组遍历并删除自身

    好了,我们回归问题的本质,怎么在遍历一个数组的同时,并删除符合条件的所有项呢?

    其实很简单,我们可以使用for循环,像这样:

    let arr = [1, 2, 1],
        i = 0,
        length = arr.length;
    
    for (; i < length; i++) {
        // 删除数组中所有的1
        if (arr[i] === 1) {
            arr.splice(i, 1);
            //重置i,否则i会跳一位
            i--;
        };
    };
    console.log(arr);//[2]

    删除符合条件的所有项,不就是过滤吗?过滤,本能想到filter方法,也很简单:

    var arr1 = arr.filter((index) => {
        return index !== 1;
    });
    console.log(arr1); //[2]

    更少的代码量,只是得新建一个变量来接受filter方法的返回值。

    你说,我这个人就比较倔强,forEach因为index索引无法重置,对于删除数组项真的很困难,那我非要用forEach去做这个功能行不行,当然行,只是我们得让数组反过来遍历:

    arr.slice().reverse().forEach(function (item, index, arr1) {
        if (item === 1) {
            arr.splice(arr1.length - 1 - index, 1);
        }
    });
    console.log(arr);//[2]
  • 相关阅读:
    Saltstack module acl 详解
    Saltstack python client
    Saltstack简单使用
    P5488 差分与前缀和 NTT Lucas定理 多项式
    CF613D Kingdom and its Cities 虚树 树形dp 贪心
    7.1 NOI模拟赛 凸包套凸包 floyd 计算几何
    luogu P5633 最小度限制生成树 wqs二分
    7.1 NOI模拟赛 dp floyd
    springboot和springcloud
    springboot集成mybatis
  • 原文地址:https://www.cnblogs.com/qianxiaox/p/14982722.html
Copyright © 2011-2022 走看看