forEach 和 map 会不会改变原数组

前言

关于 forEach 和 map 会不会改变原数组的问题,之前也看过别人的总结,自己前几次遇到这个问题的时候觉得不是很清晰,有点纸上得来终觉浅的感觉,然后自己进行了一些小实践并分享出来。

测试开始

如果你们看到这篇文章,推荐将下面代码复制运行一下,个人认为会比看文字总结感受更加深刻。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>遍历</title>
</head>
<body>

<script>
    let arr = [1, 2, 3, 4, 5]; // 普通数组;
    let objArr = [{isChanged: false},{isChanged: false}]; // 对象数组;

    // forEach 测试
    let testForEach = function(){
        // 普通数组测试
        arr.forEach((item, index) => {
            arr[index] = 0; // 这里 会 改变原数组 arr
            item = 1; // 这里 不会 改变原数组 arr
            console.log(typeof index); // index 为 number
        })
        console.log(arr); // [0, 0, 0, 0, 0] 而不是 [1, 1, 1, 1, 1]

        // 对象数组测试
        objArr.forEach((item, index) => {
            // objArr[index] = 0; // 这里 会 改变原数组 objArr
            item = 1; // 这里 不会 改变原数组 objArr
            item.isChanged = true; // 这里 会 改变原数组 objArr,数组中元素的 isChanged 属性由 false 变为了 true
            console.log(typeof index); // index 为 number
        })
        console.log(objArr); // [{isChanged: true},{isChanged: true}] 而不是 [1, 1]
    }

    // map 测试
    let testMap = function(){
        // 普通数组测试
        let tempArr1 = arr.map((item, index) => {
            item = 1; // // 这里 不会 改变原数组 arr
            arr[index] = 0; // 这里 会 改变原数组 arr
            console.log(typeof index); // index 为 number
            return item + 1;
        })
        console.log(tempArr1); // map 返回数组 [2, 2, 2, 2, 2]
        console.log(arr); // [0, 0, 0, 0, 0]

        // 对象数组测试
        let tempArr2 = objArr.map((item, index) => {
            item.isChanged = true; // 这里 会 改变原数组 objArr,对象数组中元素的 isChanged 属性由 false 变为了 true
            return item;
        })
        console.log('map 返回数组', tempArr2); // map 返回数组 [{isChanged: true},{isChanged: true}]
        console.log('原对象数组', objArr); // [{isChanged: true},{isChanged: true}]
    }

    // reduce 这里顺便用一下 reduce,可以直接跳过
    let testReduce = function(){
        let accumulation = arr.reduce((preValue, curValue, index) => {
            console.log(preValue, curValue, index); // index 为 curValue 的索引
            return preValue + curValue;
        }, 4);
        // 这里initialValue 为 4,如果不传入第二个参数 initialValue,则 index 的值为 1,preValue 为数组索引为 0 的元素 array[0],否则为 array[1]
        console.log(accumulation); // 19
    }

    // 测试函数调用
    // testForEach();
    // testMap();
    // testReduce(); // 可忽略
</script>
</body>
</html>

forEach 与 map总结

forEach 和 map 它们都用于遍历数组,并且只会保证数组中元素的首地址不会改变,但该地址所指向的值可以改变(一般是引用类型数据)。即:

  • 如果数组中的某个元素 item 为基本数据类型,在遍历过程中令 item = xxx ,那么原数组不会改变。
  • 如果 item 为对象或者其他引用数据类型,令 item.x = xxx,那么此时原数组会被改变。

此外,在 forEach 和 map 中,通过 arr[index] = xxx 可以改变元素的首地址(原数组中的元素改变)。

forEach 和 map 均不能正确响应 continue 和 break;forEach 中 return 是直接返回,map 的 return 是返回新生成的数组对应某一项的元素,如果没有返回,则该项数组元素为 undefined。

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值