JavaScript中的深浅拷贝
标签:
JavaScript
深浅拷贝
let a = { age: 1}let b = a a.age = 2console.log(b.age) // 2
从上面的例子可以发现,如果给一个变量赋值一个对象,那么两者的值会是同一个引用,其中一方改变,另一方也会相应改变。
解决这个问题,可以引入浅拷贝:
浅拷贝
可以使用
Object.assign
来解决这个问题
let a = { age: 1}let b = Object.assign({}, a) a.age = 2console.log(b.age) // 1
使用ES6展开运算符(...)解决
let a = { age: 1}let b = {...a} a.age = 2console.log(b.age) // 1
通常浅拷贝能解决大部分的问题,但是当遇到,对象里面嵌套一个对象的时候,就需要用到深拷贝了
let a = { age: 1, name: { first: 'black' } }let = {...a} a.name.first = 'guyue'console.log(b.name.first) // guyue
这样说明浅拷贝并没有对嵌套的对象生效。此时需要深拷贝上场:
深拷贝
深拷贝最简单的实现办法就是使用JSON.parse(JSON.stringify(object))
来解决。
let a = { age: 1, name: { first: 'black' } }let b = JSON.parse(JSON.stringify(a)) a.name.first = 'guyue'console.log(b.name.first) // black
但是当出现以下几种情况的时候,会出现问题:
let obj = { a: 1, b: { c: 2 } } obj.c = obj.b obj.d = obj.a obj.b.c = obj.clet newObj = JSON.parse(JSON.stringify(obj))console.log(newObj)// Uncaught TypeError: Converting circular structure to JSON
报错了,不能解决循环引用对象的问题。
let obj = { age: undefined, sex: function(){}, name: 'black'}let newObj = JSON.parse(JSON.stringify(obj))console.log(newObj) // {name: "black"}
发现只拷贝了name
,而忽略了undefined
和funcion
。
所以,JSON.parse(JSON.stringify(obj))
遇到这几种情况会出现问题:
不会拷贝
undefined
不能拷贝函数
不能解决循环引用的对象
所以采用下面的方式:
function deepClone(obj) { let res = obj instanceof Array ? [] : {} for(let k in obj) { res[k] = obj[k] if(typeof obj[k] === Object) { deepClone(obj[k]) } } return res }let obj = { age: undefined, sex: function(){}, name: 'black'}let newObj = deepClone(obj)console.log(newObj) // {age: undefined, sex: ƒ, name: "black"}
可以采用ES2017的新语法:
function copyObject(orig) { return Object.create( Object.getPrototypeOf(orig), Object.getOwnPropertyDescriptors(orig) ); }let obj = { age: undefined, sex: function(){}, name: 'black'}let newObj = copyObject(obj)console.log(newObj) // {age: undefined, sex: ƒ, name: "black"}
作者:宿雨jj
链接:https://www.jianshu.com/p/b238df26012e
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦