摘要:深淺拷貝從上面的例子可以發(fā)現(xiàn),如果給一個(gè)變量賦值一個(gè)對象,那么兩者的值會(huì)是同一個(gè)引用,其中一方改變,另一方也會(huì)相應(yīng)改變。此時(shí)需要深拷貝上場深拷貝深拷貝最簡單的實(shí)現(xiàn)辦法就是使用來解決。發(fā)現(xiàn)只拷貝了而忽略了和。
深淺拷貝
let a = { age: 1 } let b = a a.age = 2 console.log(b.age) // 2
從上面的例子可以發(fā)現(xiàn),如果給一個(gè)變量賦值一個(gè)對象,那么兩者的值會(huì)是同一個(gè)引用,其中一方改變,另一方也會(huì)相應(yīng)改變。
解決這個(gè)問題,可以引入淺拷貝:
淺拷貝可以使用Object.assign 來解決這個(gè)問題
let a = { age: 1 } let b = Object.assign({}, a) a.age = 2 console.log(b.age) // 1
使用ES6展開運(yùn)算符(...)解決
let a = { age: 1 } let b = {...a} a.age = 2 console.log(b.age) // 1
通常淺拷貝能解決大部分的問題,但是當(dāng)遇到,對象里面嵌套一個(gè)對象的時(shí)候,就需要用到深拷貝了
let a = { age: 1, name: { first: "black" } } let = {...a} a.name.first = "guyue" console.log(b.name.first) // guyue
這樣說明淺拷貝并沒有對嵌套的對象生效。此時(shí)需要深拷貝上場:
深拷貝深拷貝最簡單的實(shí)現(xiàn)辦法就是使用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
但是當(dāng)出現(xiàn)以下幾種情況的時(shí)候,會(huì)出現(xiàn)問題:
let obj = { a: 1, b: { c: 2 } } obj.c = obj.b obj.d = obj.a obj.b.c = obj.c let newObj = JSON.parse(JSON.stringify(obj)) console.log(newObj) // Uncaught TypeError: Converting circular structure to JSON
報(bào)錯(cuò)了,不能解決循環(huán)引用對象的問題。
let obj = { age: undefined, sex: function(){}, name: "black" } let newObj = JSON.parse(JSON.stringify(obj)) console.log(newObj) // {name: "black"}
發(fā)現(xiàn)只拷貝了name ,而忽略了undefined和funcion。
所以,JSON.parse(JSON.stringify(obj))遇到這幾種情況會(huì)出現(xiàn)問題:
不會(huì)拷貝 undefined
不能拷貝函數(shù)
不能解決循環(huán)引用的對象
所以采用下面的方式:
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"}
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/97019.html
摘要:開門見山,有人叫對象的復(fù)制為深復(fù)制淺復(fù)制,也有人叫深拷貝淺拷貝。高級屬性修改深拷貝滿足對象的復(fù)制,淺拷貝影響原數(shù)組。關(guān)于對象的深淺拷貝,暫且探索到這里,后續(xù)有新發(fā)現(xiàn)再進(jìn)行補(bǔ)充。 showImg(https://segmentfault.com/img/remote/1460000014305581); 開門見山,有人叫對象的復(fù)制為深復(fù)制淺復(fù)制,也有人叫深拷貝淺拷貝。其實(shí)都是copy。 ...
摘要:基本類型指的是簡單的數(shù)據(jù)段,而引用類型指的是一個(gè)對象保存在堆內(nèi)存中的地址,不允許我們直接操作內(nèi)存中的地址,也就是說不能操作對象的內(nèi)存空間,所以,我們對對象的操作都只是在操作它的引用而已。 工作中經(jīng)常會(huì)遇到需要復(fù)制 JavaScript 數(shù)據(jù)的時(shí)候,遇到 bug 時(shí)實(shí)在令人頭疼;面試中也經(jīng)常會(huì)被問到如何實(shí)現(xiàn)一個(gè)數(shù)據(jù)的深淺拷貝,但是你對其中的原理清晰嗎?一起來看一下吧! 一、為什么會(huì)有深淺...
摘要:基本數(shù)據(jù)類型的復(fù)制很簡單,就是賦值操作,所以深淺拷貝也是針對,這類引用類型數(shù)據(jù)。它會(huì)拋棄對象的。另外,查資料過程中還看到這么一個(gè)詞結(jié)構(gòu)化克隆算法還有這一篇資料也有參考,也寫得比較詳細(xì)了的深淺拷貝 基本數(shù)據(jù)類型的復(fù)制很簡單,就是賦值操作,所以深淺拷貝也是針對Object,Array這類引用類型數(shù)據(jù)。 淺拷貝對于字符串來說,是值的復(fù)制,而對于對象來說則是對對象地址的復(fù)制;而深拷貝的話,它不...
摘要:原文地址基礎(chǔ)心法深淺拷貝歡迎。上面的代碼是最簡單的利用賦值操作符實(shí)現(xiàn)了一個(gè)淺拷貝,可以很清楚的看到,隨著和改變,和也隨著發(fā)生了變化。展開運(yùn)算符結(jié)論實(shí)現(xiàn)的是對象第一層的深拷貝。 原文地址:JavaScript基礎(chǔ)心法——深淺拷貝 歡迎star。 如果有錯(cuò)誤的地方歡迎指正。 淺拷貝和深拷貝都是對于JS中的引用類型而言的,淺拷貝就只是復(fù)制對象的引用,如果拷貝后的對象發(fā)生變化,原對象也會(huì)發(fā)生...
閱讀 2137·2021-11-22 15:24
閱讀 2433·2021-09-09 11:53
閱讀 3049·2021-09-04 16:40
閱讀 1648·2019-08-30 15:52
閱讀 3367·2019-08-29 13:47
閱讀 2749·2019-08-26 17:40
閱讀 1561·2019-08-26 13:24
閱讀 2256·2019-08-26 12:01