前言

简单值(基本类型值)总是通过值复制的方式来赋值/传递 null,undefined,symbol,string,number,boolean
复杂值(对象和函数)总是通过引用复制的方式来赋值/传递 object, array, function
由于引用指向的值本身而非变量,因此一个引用无法更改另一个引用的指向
不能通过引用一个新的引用来更改旧的引用的指向,只能修改新旧引用共同指向的值
如果通过值复制的方式来传递复合值,就需要创建一个复本,这样传递的就不是原始值foo(a.slice()),foo中的操作不会影响到a指向的数组

因此会发现复杂值的赋值的时候,例如 a = obj,当我们改变a中某个属性的值时,这是obj里面对应属性的值也发生了变化,这种就是浅拷贝

如果a的属性的值发生改变,obj对应属性的值不发生变化,这种就是深拷贝

浅拷贝

浅拷贝拷贝的是引用地址,实现方式有以下几种

  • Object.assign(target, obj1, obj2...)将第二个参数及以后的参数合并到第一个对象里 – 前提传入的参数都是多层嵌套,单层的话是深拷贝
  • for...in...遍历每一个属性,将他们复制给新的对象,对象必须是多层的状态下才能实现浅拷贝 – 前提传入的参数都是多层嵌套,单层的话是深拷贝
  • $.extend(boolean?, {}, obj1, obj2...) jquery的对象扩展方法,boolean如果为true是深拷贝,不填就是浅拷贝,将第三个参数及以后的参数合并到第二个对象里 – 前提传入的参数都是多层嵌套,单层的话是深拷贝
  • es6新方法 扩展运算符 ...前提传入的参数都是多层嵌套,单层的话是深拷贝
  • Array.prototype.concat(),Array.prototype.slice()
    slice和concat方法不会修改原数组,只会返回一个浅复制了原数组中的一个新数组 对象会发生变化,String,Number,boolean不会发生变化

    深拷贝

    深拷贝拷贝的是对象的数据而不是地址

  • JSON.stringify(),JSON.parse(),

    但是使用 这种方法进行深拷贝会有一些几个问题

    1. 这个方法对于对象中包含函数不使用,因为不会拷贝函数
    2. 如果属性的值为 undefined,会在深拷贝的过程被删除
    3. RegExp,Error 对象会失去原本属性变成 {}
    4. Sympbol 不能被序列化
    5. 会丢失对象原型
    6. 存在循环引用的时候,无法正确实现深拷贝
  • es6新方法 扩展运算符 ...前提传入的参数都是多层嵌套,单层的话是深拷贝

  • loadsh

  • 手动进行递归赋值