深拷贝和浅拷贝的区别

假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。

  1. 深拷贝,是拷贝对象各个层级的属性,拷贝对象的地址。
    例如:JSON.parse(JSON.stringify())(特殊情况下无法使用,见文章末尾)
  2. 浅拷贝,指针指向堆中相同的地址,所有会改变原来的数据。
    例如:Object.assign() Array.prototype.slice()

对象的扩展运算符(…)深拷贝还是浅拷贝

  1. 如果只是一层数组或是对象,其元素只是简单类型的元素,那么属于深拷贝(即只有一层拷贝)

    let a = {
    age: 22,
    name: 'abc'
    }

    let b = {...a};
    b.age = 18;

    console.log(a.age); // 22
    console.log(b.age); // 18
  2. 如果数组或对象中的元素是引用类型的元素,那么就是浅拷贝

    let a = {
    age: 22,
    name: 'abc',
    address: {
    city: 'Anhui'
    }
    }

    let b = {...a};
    b.address.city = 'Shanghai';

    console.log(a.address.city); // Shanghai
    console.log(b.address.city); // Shanghai
  3. 如何使得深拷贝

    const obj = {
    age: 20,
    name: 'dyk',
    address: {
    city: 'anqing'
    },
    arr: ['a', 'b', 'c']
    }

    // const obj1 = JSON.parse(JSON.stringify(obj))
    const obj1 = deepClone(obj)

    obj1.address.city = 'shanghai'
    obj1.arr[1] = 666
    console.log(obj, obj1)

    function deepClone(obj) {
    if (typeof obj !== 'object' || obj == null) {
    return obj
    }

    let result
    if (obj instanceof Array) {
    result = []
    } else {
    result = {}
    }

    for (let key in obj) {
    //保证key不是原型的属性
    if (obj.hasOwnProperty(key)) {
    //递归
    result[key] = deepClone(obj[key])
    }
    }

    return result
    }

    或者利用JSON.parse(JSON.stringfy(xxx))来实现深拷贝
    注意:JSON.stringfy(xxx)的方法无法处理函数和 undefined无法处理循环引用无法处理某些特殊的 JavaScript 对象,如 RegExp、Error、Date 等,这些对象会被转换成空对象对象的原型链上的属性会丢失,如果原始对象的某个属性是通过原型链继承的,那么使用该方法得到的新对象会丢失该属性