javaScript深拷貝和淺拷貝的簡(jiǎn)單介紹
在了解深拷貝和淺拷貝之前,我們先梳理一下:
JavaScript中,分為基本數(shù)據(jù)類型(原始值)和復(fù)雜類型(對(duì)象),同時(shí)它們各自的數(shù)據(jù)類型細(xì)分下又有好幾種數(shù)據(jù)類型
基本數(shù)據(jù)類型
數(shù)字Number 字符串String 布爾Boolean Null Undefined Symbols BigInt
基本數(shù)據(jù)類型在內(nèi)存當(dāng)中,是存儲(chǔ)在棧Stack
在數(shù)據(jù)結(jié)構(gòu)當(dāng)中
- 棧在內(nèi)存上的分配的空間生命周期很短,當(dāng)變量使用完畢,方法執(zhí)行完成就被釋放掉,因此在js當(dāng)中,變量使用完畢之后,基本就被回收了,
- 有一個(gè)場(chǎng)景比較例外,閉包的情況下,變量是始終存在內(nèi)存當(dāng)中不被釋放.
- 棧存儲(chǔ)具有先進(jìn)后出,后進(jìn)先出的特點(diǎn): 1,2,3,4,5,6 => 6,5,4,3,2,1
引用數(shù)據(jù)類型
日期Dete,對(duì)象Object,數(shù)組Array,方法Function, 正則regex,帶鍵的集合:Maps, Sets, WeakMaps, WeakSets
引用數(shù)據(jù)類型與堆內(nèi)存heap的一些關(guān)系
- 在JavaScript中,不允許直接訪問堆內(nèi)存中的位置,不能直接操作對(duì)象的堆內(nèi)存空間。
- 對(duì)象的引用地址是存在棧內(nèi)存中,在我們的日常編碼過程中,操作對(duì)象的時(shí)候,讀取對(duì)象的存在棧內(nèi)存的引用地址而不是在堆中的對(duì)象,引用類型的值都是通過引用訪問。
JavaScript中堆內(nèi)存和棧內(nèi)存簡(jiǎn)易示意圖例
下面對(duì)于對(duì)象的操作,都可以參照上圖進(jìn)行思考
淺拷貝-深拷貝
淺拷貝
只是拷貝了某一層的屬性,或者某一層,沒有全部拷貝到另外的對(duì)象上
let userInfo = { name: "zhangsan", age: "29", say: function () { console.log("hello"); }, child: [ { name: "zhangsan01", }, ], };
對(duì)象解構(gòu),只能拷貝第一層對(duì)象
// 對(duì)象解構(gòu)... let info = { ...userInfo }; info.name = "lisi"; info.child.name = "lisi001"; info.say(); console.log("userInfo", userInfo); console.log("info", info); userInfo和info中的child.name都改成了---->"lisi001"
Object.assign() 第一層是深拷貝,二級(jí)屬性后就是淺拷貝
let info = {}; Object.assign(info, userInfo); info.name = "lisi"; info.child.name = "lisi001"; console.log("userInfo", userInfo); console.log("info", info);
JSON.parse(JSON.stringify());
對(duì)象可以復(fù)制,但是當(dāng)屬性是function時(shí),沒有復(fù)制到新的對(duì)象上,因此在日常的開發(fā)過程中,涉及到數(shù)組對(duì)象,使用JSON.parse(JSON.stringify());還是沒問題的
let info = JSON.parse(JSON.stringify(userInfo)); info.name = "lisi"; info.child.name = "lisi001"; console.log("userInfo", userInfo); console.log("info", info);
for in,第一層可以拷貝,第二層在修改的時(shí)候,還是使用的引用地址,前后的對(duì)象都發(fā)生了更改
let info = {}; for (let key in userInfo) { info[key] = userInfo[key]; } info.name = "lisi"; info.child.name = "lisi001"; console.log("userInfo", userInfo); console.log("info", info);
淺拷貝小結(jié)
以上淺拷貝方法,有些拷貝只能拷貝第一層,有些可以拷貝多層,
但是當(dāng)屬性類型是方法時(shí),還是淺拷貝,
因此我們?cè)陂_發(fā)中,使用淺拷貝,需要注意,同時(shí),出了拷貝function,類似正則,date等數(shù)據(jù)類型沒有一一列舉,感興趣的同學(xué)可以自己寫一些demo,去校驗(yàn)更為復(fù)雜和數(shù)據(jù)類型更豐富的數(shù)據(jù)。
深拷貝
所有的屬性都拷貝到新的對(duì)象上
使用遞歸遍歷每一個(gè)屬性,在遞歸遍歷的時(shí)候,針對(duì)每一種數(shù)據(jù)類型處理和拷貝
lodash深拷貝方法,感興趣的同學(xué),可以去閱讀lodash深拷貝的實(shí)現(xiàn)源碼
文檔地址:深拷貝cloneDeep https://www.lodashjs.com/docs/lodash.cloneDeep
更多方法,有待補(bǔ)充
結(jié)尾
當(dāng)我們操作復(fù)雜數(shù)據(jù)類型的時(shí)候,都是在操作棧內(nèi)存Stack的內(nèi)存地址,指針指向?qū)ο笤诙褍?nèi)存heap的數(shù)據(jù)。
傳入的對(duì)象是使用對(duì)象字面量{}創(chuàng)建的對(duì)象還是由構(gòu)造函數(shù)生成的對(duì)象
如果對(duì)象是由構(gòu)造函數(shù)創(chuàng)建出來(lái)的,那么是否要拷貝原型鏈上的屬性
如果要拷貝原型鏈上的屬性,那么如果原型鏈上存在多個(gè)同名的屬性,保留哪個(gè)
針對(duì)的數(shù)據(jù)類型,屬性的數(shù)據(jù)類型,各自的缺陷,適用的業(yè)務(wù)場(chǎng)景,自己造輪子or使用原生方法,工具類
到此這篇關(guān)于javaScript深拷貝和淺拷貝的文章就介紹到這了,更多相關(guān)js深拷貝和淺拷貝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
源碼地址
相關(guān)文章
javascript校驗(yàn)價(jià)格合法性實(shí)例(必須輸入2位小數(shù))
這篇文章主要介紹了javascript校驗(yàn)價(jià)格合法性實(shí)例,其中價(jià)格必須是數(shù)字且必須輸入2位小數(shù),需要的朋友可以參考下2014-05-05JS從數(shù)組中隨機(jī)取出幾個(gè)數(shù)組元素的方法
JS如何從一個(gè)數(shù)組中隨機(jī)取出一個(gè)元素或者幾個(gè)元素呢?其實(shí)方法很簡(jiǎn)單,下面小編給大家分享了JS隨機(jī)取出幾個(gè)數(shù)組元素的方法,非常不錯(cuò),需要的朋友參考下2016-08-08echarts折線圖每段顯示不同的顏色的實(shí)現(xiàn)
本文主要介紹了echarts折線圖每段顯示不同的顏色的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-09-09JS highcharts動(dòng)態(tài)柱狀圖原理及實(shí)現(xiàn)
這篇文章主要介紹了JS highcharts動(dòng)態(tài)柱狀圖原理及實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10JS擴(kuò)展類,克隆對(duì)象與混合類實(shí)例分析
這篇文章主要介紹了JS擴(kuò)展類,克隆對(duì)象與混合類,通過自定義extend,clone與augment函數(shù)實(shí)例分析了類的擴(kuò)展,對(duì)象的克隆與混合類相關(guān)實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下2016-11-11Object的相關(guān)方法 和 js遍歷對(duì)象的常用方法總結(jié)
這篇文章主要介紹了Object的相關(guān)方法 和 js遍歷對(duì)象的常用方法,結(jié)合實(shí)例形式總結(jié)分析了Object對(duì)象操作的操作方法與js遍歷的三種常用方法,需要的朋友可以參考下2023-05-05js字母大小寫轉(zhuǎn)換實(shí)現(xiàn)方法總結(jié)
本文是對(duì)js中字母大小寫轉(zhuǎn)換的實(shí)現(xiàn)方法進(jìn)行了總結(jié)介紹,需要的朋友可以過來(lái)參考下,希望對(duì)大家有所幫助2013-11-11