javascript進(jìn)階篇深拷貝實(shí)現(xiàn)的四種方式
概念介紹
深拷貝:在堆內(nèi)存中重新開(kāi)辟一個(gè)存儲(chǔ)空間,完全克隆一個(gè)一模一樣的對(duì)象 淺拷貝:不在堆內(nèi)存中重新開(kāi)辟空間,只復(fù)制棧內(nèi)存中的引用地址。本質(zhì)上兩個(gè)對(duì)象(數(shù)組)依然指向同一塊存儲(chǔ)空間
第一種:遞歸方式(推薦,項(xiàng)目中最安全最常用)
使用遞歸的方式進(jìn)行對(duì)象(數(shù)組)的深拷貝
奉上已封裝的深拷貝函數(shù)??
//函數(shù)拷貝 const copyObj = (obj = {}) => { //變量先置空 let newobj = null; //判斷是否需要繼續(xù)進(jìn)行遞歸 if (typeof (obj) == 'object' && obj !== null) { newobj = obj instanceof Array ? [] : {}; //進(jìn)行下一層遞歸克隆 for (var i in obj) { newobj[i] = copyObj(obj[i]) } //如果不是對(duì)象直接賦值 } else newobj = obj; return newobj; }
上方函數(shù)的使用方式??
//模擬對(duì)象 let obj = { numberParams:1, functionParams:() => { console.log('昨天基金全是綠的,只有我的眼睛是紅的'); }, objParams:{ a:1, b:2 } } const newObj = copyObj(obj); //這樣就完成了一個(gè)對(duì)象的遞歸拷貝 obj.numberParams = 100; //更改第一個(gè)對(duì)象的指 console.log(newObj.numberParams); //輸出依然是1 不會(huì)跟隨obj去改變
第二種:JSON.stringify() ;(這個(gè)不推薦使用,有坑)
這個(gè)方法有坑,詳細(xì)講解請(qǐng)看我另一篇文章 “使用JSON.stringify進(jìn)行深拷貝的坑” 以下是代碼示例
let obj = { a:1, b:"基金虧太多,終有一天,你站上了天臺(tái),我臥上了軌道。來(lái)生我們有說(shuō)有笑。" } //先轉(zhuǎn)為json格式字符,再轉(zhuǎn)回來(lái) let newObj = JSON.parse(JSON.stringify(obj)); obj.a = 50; console.log(newObj.a); //輸出 1
普通的對(duì)象也可以進(jìn)行深拷貝,但是?。。?當(dāng)對(duì)象內(nèi)容項(xiàng)為number,string.boolean的時(shí)候,是沒(méi)有什么問(wèn)題的。但是,如果對(duì)象內(nèi)容項(xiàng)為undefined,null,Date,RegExp,function,error的時(shí)候。使用JSON.stringify()進(jìn)行拷貝就會(huì)出問(wèn)題了。 詳細(xì)講解請(qǐng)查看我的另一篇文章“使用JSON.stringify()進(jìn)行深拷貝的坑”
第三種:使用第三方庫(kù)lodash中的cloneDeep()方法
是否推薦使用,看情況吧。如果我們的項(xiàng)目中只需要一個(gè)深拷貝的功能,這種情況下為了一個(gè)功能引入整個(gè)第三方庫(kù)就顯得很不值得了。不如寫(xiě)一個(gè)遞歸函數(shù)對(duì)于項(xiàng)目來(lái)說(shuō)性能更好。
lodash.cloneDeep()代碼示例??
import lodash from 'lodash'; let obj = { a: { c: 2, d: [1, 3, 5], e:'阿巴阿巴' }, b: 4 } const newObj = lodash.cloneDeep(obj); obj.b = 20; console.log(newObj.b); //輸出 4; 不會(huì)改變
實(shí)際上,cloneDeep()方法底層使用的本來(lái)就是遞歸方法。只是在外層又封裝了一層而已。
所以,如果不是原先項(xiàng)目中有使用 lodash 這個(gè)庫(kù)的話(huà),大可不必為了這一個(gè)功能而去引入它。
文章上方有提供進(jìn)行深拷貝的函數(shù),推薦使用。大家可自取。
第四種:JQuery的extend()方法進(jìn)行深拷貝(推薦在JQ中使用)
這個(gè)方法僅適用于JQuery構(gòu)建的項(xiàng)目。 JQuery自身攜帶的extend()方法可以進(jìn)行深拷貝,不用自己寫(xiě)遞歸也不用引入第三方庫(kù)還沒(méi)什么坑。
在JQuery項(xiàng)目中的使用方式??
let obj = { a: { c: 2, d: [1, 3, 5], e:'阿巴阿巴' }, b: 4 } let newObj= $.extend(true, {}, obj1); //拷貝完成 obj.b = 20; console.log(newObj.b); //輸出 4
總結(jié)
進(jìn)行深拷貝的方法
- 遞歸函數(shù) (推薦使用,項(xiàng)目中使用的更多,更小,更安全)
- JSON.stringify() 和JSON.parse() ; (不推薦使用,如果遇到Function,Date等類(lèi)型的變量容易出現(xiàn)一些意料之外的問(wèn)題)
- 第三方庫(kù)lodash的cloneDeep()方法 (就情況而定,如果項(xiàng)目中原先就有l(wèi)odash這個(gè)第三方庫(kù),可以使用,否則還是推薦使用遞歸函數(shù)。不然成本太高。)
- JQuery的extend()函數(shù) (推薦在JQuery項(xiàng)目中使用,其他項(xiàng)目依然推薦是用遞歸函數(shù))
以上就是javascript進(jìn)階篇深拷貝實(shí)現(xiàn)的四種方式的詳細(xì)內(nèi)容,更多關(guān)于javascript深拷貝的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序本作用域下調(diào)用全局JS詳解及實(shí)例
這篇文章主要介紹了微信小程序本作用域下調(diào)用全局JS詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02uniapp封裝canvas組件無(wú)腦繪制保存小程序分享海報(bào)
這篇文章主要為大家介紹了uniapp封裝canvas組件和方法無(wú)腦繪制并保存小程序分享海報(bào)實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08使用HTTP?Referer實(shí)現(xiàn)圖片防盜圖文示例詳解
這篇文章主要為大家介紹了使用HTTP?Referer實(shí)現(xiàn)圖片防盜圖文示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

微信小程序 開(kāi)發(fā)之滑塊視圖容器(swiper)詳解及實(shí)例代碼