深拷贝、浅拷贝
前言
简单值(基本类型值)总是通过值复制的方式来赋值/传递 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()
,但是使用 这种方法进行深拷贝会有一些几个问题
- 这个方法对于对象中包含函数不使用,因为不会拷贝函数
- 如果属性的值为 undefined,会在深拷贝的过程被删除
- RegExp,Error 对象会失去原本属性变成
{}
- Sympbol 不能被序列化
- 会丢失对象原型
- 存在循环引用的时候,无法正确实现深拷贝
es6新方法 扩展运算符
...
– 前提传入的参数都是多层嵌套,单层的话是深拷贝loadsh
手动进行递归赋值
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment
DisqusValine