摘要:動(dòng)手實(shí)現(xiàn)深拷貝利遞歸來實(shí)現(xiàn)對對象或數(shù)組的深拷貝。遞歸思路對屬性中所有引用類型的值進(jìn)行遍歷,直到是基本類型值為止。深拷貝只對對象自有屬性進(jìn)行拷貝測試數(shù)據(jù)拷貝方式其實(shí)也是一種繼承的方式,當(dāng)然繼承還是有其他方法的感謝支持
深淺拷貝 基本類型 & 引用類型
ECMAScript中的數(shù)據(jù)類型可分為兩種:
基本類型:undefined,null,Boolean,String,Number,Symbol
引用類型:Object,Array,Date,Function,RegExp等
不同類型的存儲(chǔ)方式:
基本類型:基本類型值在內(nèi)存中占據(jù)固定大小,保存在棧內(nèi)存中
引用類型:引用類型的值是對象,保存在堆內(nèi)存中,而棧內(nèi)存存儲(chǔ)的是對象的變量標(biāo)識(shí)符以及對象在堆內(nèi)存中的存儲(chǔ)地址
不同類型的復(fù)制方式:
基本類型
基本類型:從一個(gè)變量向另外一個(gè)新變量復(fù)制基本類型的值,會(huì)創(chuàng)建這個(gè)值的一個(gè)副本,并將該副本復(fù)制給新變量
let foo = 1; let bar = foo; console.log(foo === bar); // -> true // 修改foo變量的值并不會(huì)影響bar變量的值 let foo = 233; console.log(foo); // -> 233 console.log(bar); // -> 1
引用類型:從一個(gè)變量向另一個(gè)新變量復(fù)制引用類型的值,其實(shí)復(fù)制的是指針,最終兩個(gè)變量最終都指向同一個(gè)對象
let foo = { name: "leeper", age: 20 } let bar = foo; console.log(foo === bar); // -> true // 改變foo變量的值會(huì)影響bar變量的值 foo.age = 19; console.log(foo); // -> {name: "leeper", age: 19} console.log(bar); // -> {name: "leeper", age: 19}深拷貝 & 淺拷貝
淺拷貝:僅僅是復(fù)制了引用,彼此之間的操作會(huì)互相影響
深拷貝:在堆中重新分配內(nèi)存,不同的地址,相同的值,互不影響
淺拷貝舉一個(gè)例子()
var me = { name: "zjj", age: 19, address: { home: "tianjin" } }; var me_1 = { m_token: "new" }; function extend(p, c){ var c = c || {}; for(var i in p) { c[i] = p[i]; } } extend(me,me_1);深拷貝
var me = { name: "zjj", age: 19, address: { home: "tianjin" } }; var me_1 = { m_token: "new" }; function extend(p, c){ var c = c || {}; for(var i in p) { c[i] = p[i]; } } function extendDeeply(p, c) { var c = c || {}; for(var i in p) { if(typeof p[i] === "object") { // 引用類型需要遞歸實(shí)現(xiàn)深拷貝 c[i] = (p[i].constructor === Array ) ? [] : {} extendDeeply(p[i], c[i]); } else { // 非引用類型直接復(fù)制即可 c[i] = p[i]; } } } extendDeeply(me,me_1);
JSON.parse()和JSON.stringify()
JSON.stringify():把一個(gè)js對象序列化為一個(gè)JSON字符串
JSON.parse():把JSON字符串反序列化為一個(gè)js對象
let obj = { name: "leeper", age: 20, friend: { name: "lee", age: 19 } }; let copyObj = JSON.parse(JSON.stringify(obj)); obj.name = "Sandman"; obj.friend.name = "Jerry"; console.log(obj); // -> {name: "Sandman", age: 20, friend: {age: 19,name: "Jerry"}} console.log(copyObj); // -> {name: "leeper", age: 20, friend: {age: 19,name: "lee"}}
綜上,JSON.parse()和JSON.stringify()是完全的深拷貝。
動(dòng)手實(shí)現(xiàn)深拷貝 利【遞歸】來實(shí)現(xiàn)對對象或數(shù)組的深拷貝。遞歸思路:對屬性中所有引用類型的值進(jìn)行遍歷,直到是基本類型值為止。
// 深拷貝 function deepCopy(obj) { if (!obj && typeof obj !== "object") { throw new Error("error arguments"); } // const targetObj = obj.constructor === Array ? [] : {}; const targetObj = Array.isArray(obj) ? [] : {}; for (let key in obj) { //只對對象自有屬性進(jìn)行拷貝 if (obj.hasOwnProperty(key)) { if (obj[key] && typeof obj[key] === "object") { targetObj[key] = deepCopy(obj[key]); } else { targetObj[key] = obj[key]; } } } return targetObj; }
// 測試數(shù)據(jù) let a = { age: undefined, sex: Symbol("male"), jobs: function() { console.log("kkkk") }, name: "yck" } var cloneA = deepCopy(a); console.log(cloneA.age); console.log(cloneA.sex); cloneA.jobs();
拷貝方式其實(shí)也是一種繼承的方式,當(dāng)然繼承還是有其他方法的!
(感謝支持!?。?/pre>
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/96812.html
摘要:深拷貝相比于淺拷貝速度較慢并且花銷較大。所以在賦值完成后,在棧內(nèi)存就有兩個(gè)指針指向堆內(nèi)存同一個(gè)數(shù)據(jù)。結(jié)果如下擴(kuò)展運(yùn)算符只能對一層進(jìn)行深拷貝如果拷貝的層數(shù)超過了一層的話,那么就會(huì)進(jìn)行淺拷貝那么我們可以看到和展開原算符對于深淺拷貝的結(jié)果是一樣。 JS中數(shù)據(jù)類型 基本數(shù)據(jù)類型: undefined、null、Boolean、Number、String和Symbol(ES6) 引用數(shù)據(jù)類型:...
摘要:寫在前面專題系列是我寫的第二個(gè)系列,第一個(gè)系列是深入系列。專題系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點(diǎn)贊,鼓勵(lì)指正。 寫在前面 JavaScript 專題系列是我寫的第二個(gè)系列,第一個(gè)系列是 JavaScript 深入系列。 JavaScript 專題系列共計(jì) 20 篇,主要研究日常開發(fā)中一些功能點(diǎn)的實(shí)現(xiàn),比如防抖、節(jié)流、去重、類型判斷、拷貝、最值、扁平、柯里...
摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點(diǎn)提及,但是只要善于運(yùn)用,其實(shí)基于原型的繼承模型比傳統(tǒng)的類繼承還要強(qiáng)大。中文指南基本操作指南二繼續(xù)熟悉的幾對方法,包括,,。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 怎樣使用 this 因?yàn)楸救藢儆趥吻岸?,因此文中只看懂?8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...
摘要:總結(jié)綜上所述,數(shù)組的深拷貝比較簡單,方法沒有什么爭議,對象的深拷貝,比較好的方法是用的方法實(shí)現(xiàn),或者遞歸實(shí)現(xiàn),比較簡單的深復(fù)制可以使用實(shí)現(xiàn)參考資料知乎中的深拷貝和淺拷貝深入剖析的深復(fù)制 深淺復(fù)制對比 因?yàn)镴avaScript存儲(chǔ)對象都是存地址的,所以淺復(fù)制會(huì)導(dǎo)致 obj 和obj1 指向同一塊內(nèi)存地址。我的理解是,這有點(diǎn)類似數(shù)據(jù)雙向綁定,改變了其中一方的內(nèi)容,都是在原來的內(nèi)存基礎(chǔ)上做...
摘要:基本數(shù)據(jù)類型的復(fù)制很簡單,就是賦值操作,所以深淺拷貝也是針對,這類引用類型數(shù)據(jù)。它會(huì)拋棄對象的。另外,查資料過程中還看到這么一個(gè)詞結(jié)構(gòu)化克隆算法還有這一篇資料也有參考,也寫得比較詳細(xì)了的深淺拷貝 基本數(shù)據(jù)類型的復(fù)制很簡單,就是賦值操作,所以深淺拷貝也是針對Object,Array這類引用類型數(shù)據(jù)。 淺拷貝對于字符串來說,是值的復(fù)制,而對于對象來說則是對對象地址的復(fù)制;而深拷貝的話,它不...
閱讀 3233·2021-10-13 09:40
閱讀 3703·2019-08-30 15:54
閱讀 1314·2019-08-30 13:20
閱讀 2999·2019-08-30 11:26
閱讀 481·2019-08-29 11:33
閱讀 1104·2019-08-26 14:00
閱讀 2363·2019-08-26 13:58
閱讀 3371·2019-08-26 10:39