ES6深拷貝與淺拷貝
阿新 • • 發佈:2021-06-16
今天小編和大家一起探討js中深拷貝和淺拷貝,簡單一點理解就是,對於引用資料型別,深拷貝是資料引用地址不同,在改變一個數據的時候,不會影響另一個數據。而淺拷貝剛好相反。兩個資料引用的是同一個堆記憶體地址,一個數據改變的時候,會影響另一個相關的資料。
在之前的章節中,小編提起過關於物件的複製的方法,Object.assign(),但是這個方法只是針對物件的淺拷貝。大家也可以關注我的微信公眾號,蝸牛全棧。
let target = {} let source = { a:1, b:2 } Object.assign(target,source) console.log(target)// {a:1,b:2}
let target = {} let source = { a:{ b:{ c:1 } }, e:2, f:3 } Object.assign(target,source) console.log(target) // {a:{b:{c:1}},e:2,f:3}
let target = { a:{ b:{ c:1 } }, e:4, f:5, g:6 } let source = { a:{ b:{ c:1 } }, e:2, f:3 } Object.assign(target,source) console.log(target) // {a:{b:{c:1}},e:2,f:3} // 這裡面沒有將target中的g屬性和值
深拷貝(基本資料型別)
let a = 5 let b = a a = 6 console.log(a,b) // 6 5
淺拷貝(物件,兩個資料相互影響。一個數據內容改變之後會影響另一個數據)
let obj1 = { name:"lilei", age:18 } let obj2 = obj1 console.log(obj1)// {name:"lilei",age:18} console.log(obj2) // {name:"lilei",age:18} obj1.age = 30 console.log(obj1) // {name:"lilei",age:30} console.log(obj2) // {name:"lilei",age:30}
深拷貝(物件)
方式一:
let obj1 = { name:"lilei", age:18 } let str = JSON.stringify(obj1) let obj2 = JSON.parse(str) console.log(obj1) // {name:"lilei",age:18} console.log(obj2) // {name:"lilei",age:18} obj1.age = 30 console.log(obj1) // {name:"lilei",age:30} console.log(obj2) // {name:"lilei",age:18}
方式二:
// 判斷資料型別 let checkType = data => { let t = Object.prototype.toString.call(data).slice(8,-1) return t } // 只考慮物件和陣列還有基本資料型別的深拷貝 let deepClone = target => { let targetType = checkType(target) let result if(targetType === "Object"){ result = {} }else if(targetType === "Array"){ result = [] }else{ return target } for(let i in target){ let value = target[i] // 每個屬性對應的值 // 相容引用資料型別中還存在引用資料型別的情況 let valueType = checkType(value) if(valueType === "Object" || valueType === "Array"){ result[i] = deepClone(value) // 遞迴 }else{ result[i] = value } } return result }
附加:
一、JSON:JSON本質就是字串,物件鍵不用引號,JSON需要用引號
JSON.stringify(obj) // 將物件轉換成JSON格式字串 JSON.parse(obj) // 將JSON字串轉換成物件
二、typeof只能判斷基本資料型別,不能判斷引用資料型別,比如物件和陣列,返回的都是Object。可以用以下方式處理
let checkType = data => { let t = Object.prototype.toString.call(data) // let t = Object.prototype.toString.call(data).slice(8,-1) 擷取對應資料型別,比如Object和Array console.log(t) } checkType({}) // [Object Object] checkType([]) // [Object Array]