浅谈深浅拷贝

301 阅读2分钟

什么是深拷贝,什么是浅拷贝

首先我们要明白一点,js中数据类型分为:

基本数据类型 (Number, String, Boolean, Null, Undefined, Symbol)

对象数据类型 ( Object )

引用数据类型的值是保存在栈内存和堆内存中的对象。栈区内存保存变量标识符和指向堆内存中该对象的指针。当寻找引用值时,解释器会先寻找栈中的地址。然后根据地址找到堆内存的实体

浅拷贝:也就是拷贝A对象里面的数据,但是不拷贝A对象里面的子对象

深拷贝:会克隆出一个对象,数据相同,但是引用地址不同(就是拷贝A对象里面的数据,而且拷贝它里面的子对象)

现在用实例来说明

浅拷贝: 是通过对象类方法 Object.assign() 和 ...运算符进行拷贝

咱们先看一下简单的变量赋值

   let haoTian = {
        name:'浩天',
        children:{
            name:'儿子'
        }
    }
    let haiWang =haoTian
    haiWang.name = '海王'
    console.log(haiWang , 'haiWang' )
    console.log(haoTian , 'haoTian' )
此时如果修改haiWang的name属性 那么haoTian的name属性也会发生变化

接下来使用Object.assign()进行浅拷贝 看看会发生什么

   let haoTian = {
        name:'浩天',
        children:{
            name:'儿子'
        }
    }
    let haiWang = Object.assign({},haoTian)
    haiWang.name='海王'
    console.log(haoTian ,  'haoTian')
    console.log(haiWang , 'haiWang' )
这个时候我们改变一下 haiWang 的name属性 会发现haoTian的 name属性不会发生变化

但是修改haiWang的children属性内部的name的话 会发现haoTian children属性内部的name也会跟着发生变化
    let haoTian = {
        name:'浩天',
        children:{
            name:'儿子'
        }
    }
    let haiWang = Object.assign({},haoTian)
    haiWang.children.name='女儿'
    console.log(haoTian ,  'haoTian')
    console.log(haiWang , 'haiWang' )

这就是因为 haiWang 拷贝haoTian对象里面的数据,但是不拷贝haoTian对象里面的子对象

深拷贝: 通过JSON.parse(JSON.stringify())方法进行拷贝

    let haoTian = {
        name:'浩天',
        children:{
            name:'儿子'
        }
    }
    let haiWang = JSON.parse(JSON.stringify(haoTian))
    haiWang.name='海王'
    haiWang.children.name='女儿'
    console.log(haoTian ,  'haoTian')
    console.log(haiWang , 'haiWang' )

通过JSON.parse(JSON.stringify())拷贝的变量 无论你怎么修改都不会影响到你copy的变量

什么时候会用到深拷贝呢

这里简单提一下redux的的三大原则里

1、单一数据源
2、state是只读的
3、使用纯函数修改state

因为state是只读的 不能够被修改 所以在使用纯函数修改state的时候要对state进行深拷贝 这样无论你怎么修改拷贝的变量 都不会对state进行任何改变