1. 前言
1.很早之前寫了純文本的深淺拷貝
- 好不容易有空 改個
markdown版本的
2. 是什么 what
深淺拷貝理解,拷貝就是復(fù)制,js對引用類型數(shù)據(jù)的數(shù)據(jù)拷貝
淺拷貝 :由于引用類型數(shù)據(jù)是存在堆內(nèi)存中,堆內(nèi)存中存放的是引用類型的值,同時引用數(shù)據(jù)有會指針指向棧內(nèi)存,淺拷貝的指針指向棧內(nèi)存是一致的,所以一個改變另一個也會受影響。
深拷貝:是在堆內(nèi)存開啟新的空間存放數(shù)據(jù)。
簡單理解就是:
如果拷貝產(chǎn)生新的數(shù)據(jù)就是深拷貝,
如果只是數(shù)據(jù)的引用,就是淺拷貝
3. 應(yīng)用場景
- react redux
- table列表修改 彈出 表單
editRow(rowData) {
ElMessage.success("點擊了 編輯")
console.log("編輯數(shù)據(jù):", rowData)
this.editForm = rowData
this.editDialog = true
},
- 這里不使用深拷貝的話
diaog隨便修改不進(jìn)行保存也影響 界面的數(shù)據(jù)
4. 第三方依賴
5. 栗子
let people = {name:'yzs',age:21,sex:true}
let obj = JSON.parse(JSON.stringify(test))
obj.name = 'yqq'
people.name 輸出 'yzs'
哈哈是不是 so easy But 也有弊端
- 無法復(fù)制函數(shù),正則
- 原型鏈沒了,對象就是object,所屬的類沒了
- 循環(huán)引用的問題,沒解決
- 當(dāng)然jQ 的
extend函數(shù)也可以實現(xiàn)深復(fù)制,但是我目前jQ基本不用了
6.淺復(fù)制代碼
let people = {name:'yzs', age:28}
// 調(diào)用
let shallowObj = shallowCopy(people)
// 方法
shallowCopy = (obj)=>{
var temp = {}
for (const prop in obj){
if( Object.prototype.hasOwnProperty.call(obj,prop) ){
temp[prop] = obj[prop]
}
}
return temp
}
只復(fù)制一層對象的屬性,也就是說淺復(fù)制是對對象地址的復(fù)制,修改其中一個對象的屬性,則另一個對象的屬性也會隨之改變,這就導(dǎo)致people.name和shallowObj.name指向同一塊內(nèi)存地址
影響
shallowObj.name = 'yqq'
people.name 結(jié)果也是'yqq' 而不是原來的'yzs'
7.深復(fù)制代碼
let people = {name:'yzs', age:28}
// 調(diào)用
let shallowObj =deepCopy(people)
// 方法
deepCopy = oldObj=>{
var newObj = newObj || {}
for (const i in oldObj){
if(typeof oldObj[i] ==='object'){
if(oldObj[i] ===null){
newObj[i] =null
}else {
if(oldObj[i].constructor === Array){
newObj[i] = []
}else {
newObj[i] = {}
}
}
deepCopy(oldObj[i],newObj[i])
}else{
newObj[i] = oldObj[i]
}
}
return newObj
}
深復(fù)制會遞歸賦值對象所有層級,也就是說深復(fù)制會開辟新的棧,所以2個對象對象不同的地址,修改其中一個對象的屬性,不會改變另一個對象的屬性
不影響
shallowObj.name = 'yqq'
people.name 結(jié)果'yzs'
8. 深拷貝的另類方式
- 將需要 深拷貝的 對象 進(jìn)行
JSON.stringify()序列化- 在進(jìn)行
JSON.parse()反序列化- 缺點: 比如對象中不能存在循環(huán)引用
9. 數(shù)組
擴(kuò)展運算符
console.log(...[1, 2, 3])
// 1 2 3
console.log(...[1, [2, 3, 4], 5])
// 1 [2, 3, 4] 5
數(shù)組 api
- slice()
10. 對象淺拷貝
擴(kuò)展運算符
let outObj = {
inObj: {a: 1, b: 2}
}
let newObj = {...outObj}
newObj.inObj.a = 2
console.log(outObj) // {inObj: {a: 2, b: 2}}
Object.assign()
let outObj2 = {
inObj: {a: 1, b: 2}
}
let newObj = Object.assign({}, outObj2)
newObj.inObj.a = 2
console.log(outObj2) // {inObj: {a: 2, b: 2}}
- 都是淺拷貝
Object.assign()方法接收的第一個參數(shù)作為目標(biāo)對象,后面的所有參數(shù)作為源對象。然后把所有的源對象合并到目標(biāo)對象中。它會修改了一個對象,因此會觸發(fā) ES6 setter。
擴(kuò)展操作符(…)使用它時,數(shù)組或?qū)ο笾械拿恳粋€值都會被拷貝到一個新的數(shù)組或?qū)ο笾?。它不?fù)制繼承的屬性或類的屬性,但是它會復(fù)制ES6的 symbols 屬性。