乐趣区

js数组已经实现深拷贝但是修改其中一个数组的值其他数组的值会改变

js 变量分为值类型和引用类型,数组属于引用类型。
值类型

var a=100;

var b=a;

a=200;

console.log(b);//100   ** 值类型的特点:它每个变量都能存储各自的值,不会相互影响 **

引用类型

var a={age:20};

var b=a;

b.age=21;

console.log(a.age);//21  ** 引用类型的特点:不同变量之间的值,会相互影响 **`

值类型和引用类型的特点

 特点:从内存中来说,值类型是把每一个值都存到变量内存的位置,比如 a 存了 100,把 b 赋值给 a,b 的位置又存了 100 这个数字,a 的位置把 100 改成 200,b 的位置等于 100,还是 100,所以它不会相互影响。引用类型他不一样,引用类型是把 a 赋值成一个对象,这个对象存在另一个地方,a 内存的位置是通过一个指针指向这个对象的地方,把 b 赋值成 a 的时候,其实是定义了一个 b,b 的指针又指向了那个对象的位置,所以这个 age=20 这个对象只有一份,a 和 b 同时指向了这个对象而已,所以说当执行第三行 b.age=21 的时候,那个 age 的值已经改成了 21,所以 a 也是指向这个对象,所以说 a.age 也是 21。

引用类型为什么要这样做,而不是直接拷贝也存储一份?

 引用类型可以无限制扩展属性,比如现在它有个 age 属性,我们也可以加 name 属性啊,grade 属性啊,等等等等很多属性,属性加多了之后,会出现内存占用比较多的问题。在值类型中 a =100,把 b 赋值成 a,相当于把 100 又重新拷贝了一份存下,没有关系,因为 100 不会占用很多内存。如果这个地方把 a 赋值成一个对象,但是它又特别大,b 再赋值成 a,b 也拷贝复制一份,他就会占很大的空间,这是不合理的,所以说为了让内存共用空间,才会出现引用类型这种方式。

深拷贝

let arr=[{
                name:'111',
                title:'111',
                children:[{
                    name:'111-1',
                    title:'111-1'
                },{
                    name:'111-2',
                    title:'111-2'
                }]
            }]
            let newArr=arr.slice(0)
            for(let i of newArr){var arr2 = i.children.filter((item2) => {return item2.name === '111-1'})
                    i.children=arr2
            }
            console.log('arr',arr)
            console.log('newArr',newArr)


根据上面打印可以看到,深拷贝之后还是改变了 arr 的值,这个时候我们可以用 JSON.parse 和 JSON.stringify 来实现。

let arr=[{
                name:'111',
                title:'111',
                children:[{
                    name:'111-1',
                    title:'111-1'
                },{
                    name:'111-2',
                    title:'111-2'
                }]
            }]
            let newArr=JSON.parse(JSON.stringify(arr))
            for(let i of newArr){var arr2 = i.children.filter((item2) => {return item2.name === '111-1'})
                    i.children=arr2
            }
            console.log('arr',arr)
            console.log('newArr',newArr)

这样 arr 就不会受影响了。

退出移动版