数组方法forEach和map区别&提前结束循环有哪些方法

1.相同点

都是用来遍历一个数组并对数组的每一项执行给定的函数

不同点

  1. 从它们各自的定义中即可发现数组调用 map 方法之后会返回一个新的数组,而数组调用 forEach 之后是没有返回值,即一定返回 undefined
  2. 它们的使用场景不同,map 适用于需要更改数组的场景,而 forEach 更适用于打印数组内容,并且 forEach 除了抛出异常以外,没有办法中止或跳出循环,若要提前结束循环,则可以使用 for 循环、for···of、for···in、every、some、find、findIndex,对于需要判断一个数组是否满足条件并返回 true 或 false 的场景可以用 every() 或者 some()
     

2.map是否改变原数组

首先数组中每一项为基本数据类型的时候不改变原数组

  var a=[1,2,3,4,5];

    var b=a.map((item)=>item+10);

    console.log('原来的数组a');

    console.log(a);//[1,2,3,4,5]

    console.log('经过map处理a后的数组b');

    console.log(b);//[11,12,13,14,15]

    console.log('处理后原来的数组a');

    console.log(a);//[1,2,3,4,5]

其次当数组每一项为对象时会改变原数组

   var aa=[

        {name:'zs',age:10},

        {name:'ls',age:20},

        {name:'ww',age:30},

        {name:'zl',age:40}

    ];

    var bb=aa.map((item)=>item.age=100);

    console.log('原数组aa');

    console.log(aa);

    console.log('经过map处理后的数组bb');

    console.log(bb);

    console.log('处理后原数组aa');

    console.log(aa);

这是因为 map 和 forEach 的 callback 在操作数组元素时实际上是下面这样操作的:callback.call([thisArg], this[index], index, this),当数组元素为引用类型时, this[index] 取到的实际只是一个指向对应元素的地址,这种情况下再进行修改操作,修改的是堆中的对象的内容,那当我们再次去读取原数组中内容时,读到这个引用类型的元素时,我们拿到的还是那个地址,不过它指向的堆中的内容却已经变了
 

3.避免原数组发生改变:

    let array = [{ name: 'Anna', age: 16 }, { name: 'James', age: 18 }]
    let newArray=array.map((item) => {
      const obj = { ...item, like:'eat'};
      return obj;
    })
    console.log(array); // [{ name: 'Anna', age: 16},{ name: 'James', age: 18}]
    console.log(newArray);//[{ name: 'Anna', age: 16,like: "eat"},{ name: 'James', age: 18,like: "eat"}]

4.哪些遍历数组方法可以跳出循环

想要数据大于3的时候跳出循环

let arr = [1, 2, 3, 4, 5];

不能跳出循环的方法

forEach  ,   map   ,  reduce  ,  filter

    // 1.forEach():代替普通的for循环   执行结果全部可以打印
    {
        arr.forEach(function (val, index, arr) {
            if (val > 3) {
                console.log(val) // 4  5
                return false;    //没有返回值,ruturn false 仍向下执行
 
            } else {
                console.log(val)// 1  2  3
                return true;
            }
 
        })
 
        console.log(arr)   //[1, 2, 3, 4, 5]
    }
 
    //  2. map():非常有用   数据交互的时候  有返回值
    {
        let res = arr.map(function (val, index, arr) {
            if (val > 3) {
                console.log(val) // 4  5
                return false;    //
 
            } else {
                console.log(val)// 1  2  3
                return true;
            }
 
        })
        console.log(res)  // [true, true, true, false, false]
        console.log(arr)   //[1, 2, 3, 4, 5]
    }
 
    // 3.filter()  过滤一些不合格的数据  有返回值
 
    {
        let res = arr.filter(function (val, index, arr) {
            if (val > 3) {
                console.log(val) // 4  5
                return false;    //
 
            } else {
                console.log(val) // 1  2  3
                return true;
            }
 
        })
        console.log(res)   // [1,2, 3]
        console.log(arr)   //[1, 2, 3, 4, 5]
    }

可以跳出循环的方法

for ,  for...of  ,  some  ,   every

    // 4. some   类似查找  只有某一个元素符合条件,返回true   return true的时候跳出整个循环
    {
        let res = arr.some(function (val, index, arr) {
            if (val > 3) {
                return true;   //当内部return true时跳出整个循环
            }
 
            console.log(val)// 1 2  3
 
        })
 
        console.log(res)   //true
        console.log(arr)   //[1, 2, 3, 4, 5]
 
    }
 
    //every 当内部return false时跳出整个循环(return true;也是需要写)   数组里的所有元素都要符合条件才返回true
    {
        let res = arr.every(function (val, index, arr) {
            if (val > 3) {
                console.log(val)// 4
                return false;
            }
            else {
                console.log(val) // 1  2  3
                return true;
            }
 
        })
 
        console.log(res)   //false
        console.log(arr)   //[1, 2, 3, 4, 5]
 
    }
 
    //for-of遍历  里面不能用return  报错
    {
        for (var value of arr) {
            if (value > 3) {
                console.log(value)// 4
                break;
 
            }
 
        }
    }
 
    //for循环
    {
        for (let i = 0; i < arr.length; i++) {
            if (arr[i] > 3) {
                console.log(arr[i])  // 4
                break;
            }
 
        }
    }


参考原文链接:https://blog.csdn.net/Anna0115/article/details/103696124

参考原文链接:https://blog.csdn.net/qq_41306423/article/details/107988831
参考原文链接:https://blog.csdn.net/Candy_mi/article/details/102589856

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java 中使用 Map.forEach循环中,需要使用 final 修饰的常量数组是因为 forEach 方法使用的是内部迭代器,该迭代器使用了闭包的概念,闭包中可能会引用到外部的变量。如果不使用 final 修饰,则外部的变量可能会被修改,而在闭包中使用的这个变量的值可能会发生变化,这会导致结果的不确定性。因此,为了保证结果的可预测性和程序的正确性,Java 中的 forEach 方法要求使用 final 修饰的常量数组。 ### 回答2: 在Java中使用map.forEach时,循环体内的变量和参数必须是final修饰的常量数组,而不能使用基本类型和包装类型的原因如下: 1. map.forEach方法使用了Lambda表达式,Lambda表达式的特点是闭包,它可以捕获外部的变量。在循环体内部,Lambda表达式可能对外部的变量进行修改,因此外部的变量必须是不可变的,即final修饰的常量。 2. 对于基本类型和包装类型的值,赋值操作实际上是将新值赋给了一个新的变量,而原来的变量仍然指向原来的值。在循环体内部对基本类型和包装类型的变量进行修改操作,相当于修改了新变量的值,而不是原来的变量指向的值。因此,如果在循环体内部修改基本类型和包装类型的值,循环体外部的值不会受到影响。 3. Java中的基本类型和包装类型都是值传递,而不是引用传递。在循环体内部对基本类型和包装类型的变量进行修改,并不会影响到循环体外部的值。因此,为了保证循环体内部对变量的修改能够生效,必须使用final修饰的常量,以保证循环体内外的变量引用的是同一个对象。 综上所述,为了确保在使用map.forEach时,循环体内部对变量的修改生效,仅能使用final修饰的常量数组。这样可以保证循环体内外的变量引用的是同一个对象,从而使得循环体内部对变量的修改能够影响到循环体外部的值。 ### 回答3: 在Java中,当我们在forEach循环内部使用局部变量时,该变量必须是final修饰的常量数组,而不能是基本类型或包装类型。 这是因为forEach循环是通过迭代器来遍历集合,而迭代器在循环中是一个匿名内部类实现的。正常情况下,局部变量在栈上分配内存,当调用方法结束后,栈帧被销毁,局部变量也随之销毁。但是对于匿名内部类来说,它可能会在循环过程中被多次使用,而不像普通局部变量那样只有一次。所以,为了保证在匿名内部类中能够访问到局部变量,Java要求我们将局部变量声明为final,这样在内部类中就能够正确访问了。 但基本类型和包装类型在Java中有一个特点,即它们是值传递。这意味着,当我们将基本类型或包装类型作为参数传递给方法时,实际上传递的是其值的一个副本,而不是对原始值的引用。因此,在forEach循环内部使用final修饰的基本类型或包装类型并没有太大的实际意义,因为它们在循环中使用的是它们的副本,而不是原始值。 综上所述,为了在forEach循环中能够正确访问局部变量,我们需要将其声明为final修饰的常量数组。这样,在循环中我们使用的是该常量数组的引用,而不是对它的拷贝,这样就确保了匿名内部类能够正确访问到这个数组

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值