javascript進階篇深拷貝實現的四種方式
概念介紹
深拷貝:在堆內存中重新開辟一個存儲空間,完全克隆一個一模一樣的對象 淺拷貝:不在堆內存中重新開辟空間,隻復制棧內存中的引用地址。本質上兩個對象(數組)依然指向同一塊存儲空間
第一種:遞歸方式(推薦,項目中最安全最常用)
使用遞歸的方式進行對象(數組)的深拷貝
奉上已封裝的深拷貝函數👇
//函數拷貝 const copyObj = (obj = {}) => { //變量先置空 let newobj = null; //判斷是否需要繼續進行遞歸 if (typeof (obj) == 'object' && obj !== null) { newobj = obj instanceof Array ? [] : {}; //進行下一層遞歸克隆 for (var i in obj) { newobj[i] = copyObj(obj[i]) } //如果不是對象直接賦值 } else newobj = obj; return newobj; }
上方函數的使用方式👇
//模擬對象 let obj = { numberParams:1, functionParams:() => { console.log('昨天基金全是綠的,隻有我的眼睛是紅的'); }, objParams:{ a:1, b:2 } } const newObj = copyObj(obj); //這樣就完成瞭一個對象的遞歸拷貝 obj.numberParams = 100; //更改第一個對象的指 console.log(newObj.numberParams); //輸出依然是1 不會跟隨obj去改變
第二種:JSON.stringify() ;(這個不推薦使用,有坑)
這個方法有坑,詳細講解請看我另一篇文章 “使用JSON.stringify進行深拷貝的坑” 以下是代碼示例
let obj = { a:1, b:"基金虧太多,終有一天,你站上瞭天臺,我臥上瞭軌道。來生我們有說有笑。" } //先轉為json格式字符,再轉回來 let newObj = JSON.parse(JSON.stringify(obj)); obj.a = 50; console.log(newObj.a); //輸出 1
普通的對象也可以進行深拷貝,但是!!! 當對象內容項為number,string.boolean的時候,是沒有什麼問題的。但是,如果對象內容項為undefined,null,Date,RegExp,function,error的時候。使用JSON.stringify()進行拷貝就會出問題瞭。 詳細講解請查看我的另一篇文章“使用JSON.stringify()進行深拷貝的坑”
第三種:使用第三方庫lodash中的cloneDeep()方法
是否推薦使用,看情況吧。如果我們的項目中隻需要一個深拷貝的功能,這種情況下為瞭一個功能引入整個第三方庫就顯得很不值得瞭。不如寫一個遞歸函數對於項目來說性能更好。
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; 不會改變
實際上,cloneDeep()方法底層使用的本來就是遞歸方法。隻是在外層又封裝瞭一層而已。
所以,如果不是原先項目中有使用 lodash 這個庫的話,大可不必為瞭這一個功能而去引入它。
文章上方有提供進行深拷貝的函數,推薦使用。大傢可自取。
第四種:JQuery的extend()方法進行深拷貝(推薦在JQ中使用)
這個方法僅適用於JQuery構建的項目。 JQuery自身攜帶的extend()方法可以進行深拷貝,不用自己寫遞歸也不用引入第三方庫還沒什麼坑。
在JQuery項目中的使用方式👇
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
總結
進行深拷貝的方法
- 遞歸函數 (推薦使用,項目中使用的更多,更小,更安全)
- JSON.stringify() 和JSON.parse() ; (不推薦使用,如果遇到Function,Date等類型的變量容易出現一些意料之外的問題)
- 第三方庫lodash的cloneDeep()方法 (就情況而定,如果項目中原先就有lodash這個第三方庫,可以使用,否則還是推薦使用遞歸函數。不然成本太高。)
- JQuery的extend()函數 (推薦在JQuery項目中使用,其他項目依然推薦是用遞歸函數)
以上就是javascript進階篇深拷貝實現的四種方式的詳細內容,更多關於javascript深拷貝的資料請關註WalkonNet其它相關文章!