步步为营之JavaScript

JS-对象拷贝-深拷贝&浅拷贝

2020-06-18  本文已影响0人  刘淘

前置知识:
JavaScript中数据类型分为基本数据类型(number string boolean null undefined symbol )、引用数据类型(object)。
基本数据类型的拷贝是值拷贝,全部都是深拷贝;只有引用类型才分深拷贝、浅拷贝。

个人的理解:
为什么递归遍历重新赋值一下就可以达到深拷贝了呢?
因为将数组值遍历一下,就相当于是基本数据类型拷贝了呀。

//for循环进行浅拷贝

const resFor={}
for(const key in user){
    resFor[key]=user[key]
}
//console.log(JSON.stringify(resFor,null,2))
resFor.name='xxx'
resFor.arry=resFor.arry.join('=')
//console.log(user.name)
console.log(JSON.stringify(user),JSON.stringify(resFor))
//打印出结果 发现user的name并未改变,不是说浅拷贝只拷贝引用呢 一个变化都变化嘛
//再好好想一下,深浅拷贝都是相对于引用数据类型来说的,对于基本数据类型默认就是深拷贝
//对arry进行push操作的时候,发现拷贝对象变化了,原对象也变化了,变异方法+引用类型+浅拷贝
//当前user对象的属性都是基本数据类型,所以for循环就深拷贝了

image.png
const user={colors:[1,2]}
const resExpand={ ...user }
//使用扩展运算符进行浅拷贝
resExpand.colors=resExpand.colors.join(',') //数组非变异方法操作
console.log(JSON.stringify(user),'浅拷贝出来的数组:'+JSON.stringify(resExpand)) 
//打印结果:浅拷贝出来的数组变了,原对象数组并未改变

const user2={colors:[1,2]}
const resExpand2={ ...user2 }
resExpand2.colors.push(666) //数组变异方法操作
console.log(JSON.stringify(user2),'浅拷贝出来的数组:'+JSON.stringify(resExpand2)) 
//打印结果:浅拷贝出来的数组变了,原对象数组也改变

//resExpand={...user}
//数组转成字符串 join 或者直接toString()
//join不是变异方法 所以没有影响到原对象
/**日常将表单数据,传给接口之前,会将表单数据通过Object.assign拷贝一份作为submitFormData,然后处理submitFormData中的数组转成字符串。
*之前在网上看到说Object.assign是浅拷贝的时候我还在疑惑,为什么是浅拷贝原表单的数组没有变化呢,现在明白了,数组转字符串这个操作不是数组变异方法,
* 对数组进行变异方法操作 触发深拷贝,对数组进行非变异方法操作不会触发深拷贝
*/
const user = { name: 'xiamu', colors: [1, 2] }
//使用Object.assign()进行浅拷贝
const resAssign=Object.assign({},user,{name:'xiaomuu'},{colors:[1,2]})
//JSON.parse(JSON.Stringify())深拷贝对比
//const resAssign = JSON.parse(JSON.stringify(user))
resAssign.colors.push(44)
console.log(JSON.stringify(user),JSON.stringify(resAssign))

通过递归进行深拷贝

const user = { name: 'xiamu', colors: ["red", "green"] }

//通过递归进行深拷贝
function deepCloneByRecursive(obj) {
    const res = obj instanceof Array ? [] : {}
    for (const [key, val] of Object.entries(obj)) {
        res[key] = typeof val === 'object' ? deepCloneByRecursive(val) : val
    }
    return res
}

const copyObj=deepCloneByRecursive(user)

copyObj.colors.push('black')
console.log(`原对象数据${JSON.stringify(user)}  
拷贝后的数据${JSON.stringify(copyObj)}`)
image.png
上一篇 下一篇

猜你喜欢

热点阅读