forEach究竟能不能改变原数组?

  • Post author:
  • Post category:其他




forEach究竟能不能改变原数组?


为什么使用forEach改变了数组中的某个值之后,数组却还是原模原样?让我们一起来试一试吧。

首先,准备一个简单的数字数组,改变了num的值之后,数组没有变化。

//数组-基本数据类型
let array = [1,2,3,4];

array.forEach(num => {
    if(num === 4){
        num = 5
    }    
 })
 console.log(array)  //[1,2,3,4]
array.forEach(num => {
    if(num === 4){
        console.log(num === array[3])  //true
    }
})

num和array[3]是全等的,但是数组又没有改变,怎么解释呢?实际上,因为它们都是基本数据类型,因此只要值一样,就是全等的。

        let a = 1;
        let b = 1;
        console.log(a === b)  //true

接着试一下复杂一点的引用类型数组:

        //数组-基本数据类型
        let array = [
            {
                name: '小红',
                age: 12
            },
            {
                name: '小明',
                age: 18
            },
        ];

        array.forEach(person => {
            if(person.name === '小红'){
                person.age = 15
                console.log(person === array[0])  //true
            }
        })

        console.log(array)  //[{name: '小红',age: 15},{name: '小明',age: 18},]

可以看到,小红的年龄确实改变了,这是不是说明引用数据类型就可以被自由的改变呢?下面尝试一下改变整个person:

        array.forEach(person => {
            if(person.name === '小红'){
                person = {
                    name: '小红',
                    age: 15
                },
                console.log(person === array[0])  //false
            }
        })

        console.log(array)  //[{name: '小红',age: 12},{name: '小明',age: 18},]

可以发现用这种方式改变数组是不行的。


结论:forEach不能改变数组本身,无论是基础数据类型还是引用数据类型都不可以。


但是!可以用改变person.age的方式改变数组,原理在这儿:

在这里插入图片描述

person是一个对象,它里面存的其实是一个

指针

,这个指针存在栈内存(相当于浅层的存储区,用来存一些基本的简单数据)里面,这个指针指向的是堆内存里面的实际数据,也就是说,你拿到的person不是{name: ‘小红’,age: 15}这串数据本身,而是指向这串数据的地址,forEach里面不允许改变person的值,也就是说这个地址是改变不了的,就比如里面存的是‘湖滨小区1幢204’,这个地址被保护起来了,person也就只能指向这间房间,但是如果不改变房间,把房间里住的人变了可以吗?当然可以,这个forEach就管不着了,所以改变person.age就相当于把房间里的人给换了,相当于偷梁换柱,是可以实现的,这样就改变了array。

所以,最好不要尝试用forEach来改变数组的值,用for循环都比它好使。要在forEach里面改变数组,需要用array[index]的方法来改变数组本身。这样就需要在forEach里面穿第二个参数index。

        array.forEach((person, index) => {
            if(person.name === '小红'){
                array[index].age = 15
            }
        })

        console.log(array)  //[{name: '小红',age: 15},{name: '小明',age: 18},]



版权声明:本文为likepotato原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。