深拷贝与浅拷贝

浅拷贝:藕断丝连
深拷贝:老死不相往来

浅拷贝:arr.slice() arr.concat() 还有ES6定义的Object.assign() 第一个参数为目标参数,之后跟一个或多个源对象

  • 赋值号对于基本类型是深拷贝,对于引用类型是浅拷贝

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    let a = 1
    let b = a
    b = 2
    console.log(a,b);//1 2 深拷贝

    let arr = [1,2,3]
    let brr = arr
    brr.push(4)
    console.log(arr,brr); //[1,2,3,4] [1,2,3,4] 浅拷贝

    let obj = {
    name: "ni",
    age: 18,
    attr: {sex:'女',x:"student"}
    }
    let newObj = obj
    newObj.age = 28
    newObj.attr.x = 'teach'
    console.log(obj,newObj); //都改变 浅拷贝
  • 解构赋值对于一维变量来说是深拷贝,对于多维变量来说是浅拷贝

    1
    2
    3
    4
    5
    6
    7
    8
    9
    let arr2 = [1,2,3]
    let newArr2 = [...arr2] //解构赋值是浅拷贝
    newArr2.push(5)
    console.log(arr2,newArr2);//不受影响 一维 深拷贝

    let arr3 = [1,2,[5,4]]
    let newArr3 = [...arr3]
    newArr3[2].push(9)
    console.log(arr3,newArr3); //受影响 二维 浅拷贝
  • 实现深拷贝–函数库lodash的cloneDeep方法
    1
    2
    3
    4
    var _ = require('lodash');
    var obj1 = {
    }
    var obj2 = _.cloneDeep(obj1);
  • 实现深拷贝—快速实现
    一行代码解决,受限(function,undefined,复杂对象都不行)
    1
    2
    let newObj = JSON.parse(JSON.stringify(obj))    //实现深拷贝 
    //function,undefined类型不行,复杂对象不行
  • 实现深拷贝–通用方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    //深拷贝
    function deepClone(obj) {
    //判断是数组还是对象 所有基类是Array | Object
    const targetObj = obj.constructor === Array ? []:{}
    for(let keys in obj){
    //容错处理 判断obj中是否有keys属性
    if(obj.hasOwnProperty(keys)){
    if(obj[keys] && typeof obj[keys] === "object"){
    //处理对象和数组 因为typeof数组也是object
    //小的 临时的 容器
    targetObj[keys] = obj[keys].constructor === Array ? []:{}
    //递归
    targetObj[keys] = deepClone(obj[keys])
    }else{
    //基本数据类型
    targetObj[keys] = obj[keys]
    }
    }
    }
    return targetObj
    }

    let newObj = deepClone(obj)
    newObj.age = 28
    newObj.attr.x = 'teach'
    console.log(obj,newObj); //obj不变 深拷贝