JS中的深拷貝和淺拷貝有什么區(qū)別?

淺拷貝和深拷貝的核心區(qū)別在于是否創(chuàng)建原對象的完整獨立副本。1. 淺拷貝僅復制對象第一層屬性,若屬性為引用類型則復制其地址,常見方法包括Object.assign、擴展運算符和數(shù)組的slice()、concat(),修改嵌套對象會影響原對象;2. 深拷貝遞歸復制所有層級,生成完全獨立對象,常用方法有JSon序列化反序列化(有局限)或遞歸函數(shù)實現(xiàn),修改拷貝后對象不影響原對象;3. 選擇依據(jù)是對象結構復雜度,簡單結構用淺拷貝更高效,復雜嵌套結構需深拷貝避免副作用;4. 實現(xiàn)簡易深拷貝可用遞歸函數(shù),但應對復雜情況建議使用第三方庫如lodash的clonedeep。理解兩者差異對日常開發(fā)至關重要。

JS中的深拷貝和淺拷貝有什么區(qū)別?

JavaScript中,深拷貝和淺拷貝的核心區(qū)別在于:是否創(chuàng)建了原對象的完整獨立副本。簡單來說,淺拷貝只是復制了對象的引用地址,新舊對象共享同一塊內(nèi)存;而深拷貝會遞歸復制對象的所有層級,形成一個完全獨立的新對象。


什么是淺拷貝?

淺拷貝指的是只復制對象的第一層屬性,如果屬性是引用類型(比如數(shù)組或?qū)ο螅敲磸椭频氖撬鼈兊囊玫刂罚皇莿?chuàng)建新的對象。

常見使用場景:

  • 使用 Object.assign({}, obj) 或擴展運算符 {…obj}
  • 數(shù)組的 slice()、concat() 等方法

舉個例子:

const original = { a: 1, b: { c: 2 } }; const copy = Object.assign({}, original);  copy.b.c = 3; console.log(original.b.c); // 輸出 3,說明原對象也被修改了

這說明,雖然第一層是獨立的,但嵌套的對象仍然指向同一個地方。


什么是深拷貝?

深拷貝是指將對象的所有層級都復制一份,生成一個完全獨立的新對象。無論對象結構多復雜,修改拷貝后的對象都不會影響原始對象。

實現(xiàn)方式有多種:

  • 手動遞歸遍歷對象(適合控制細節(jié))
  • 使用 json 序列化反序列化(簡單但有限制)

例如用 JSON 的方法:

const original = { a: 1, b: { c: 2 } }; const copy = JSON.parse(JSON.stringify(original));  copy.b.c = 3; console.log(original.b.c); // 輸出 2,說明原對象沒有被影響

不過要注意這種方法的局限性:


如何選擇深拷貝還是淺拷貝?

這取決于你是否需要完全獨立的對象副本。

如果你只需要操作對象的一層屬性,或者確定對象不包含嵌套結構,那淺拷貝已經(jīng)足夠,效率也更高。

但如果對象結構復雜,特別是嵌套了其他對象或數(shù)組時,就需要使用深拷貝來避免副作用。

一些實際場景:

  • 表單數(shù)據(jù)初始化(淺拷貝即可)
  • 狀態(tài)快照保存(如撤銷功能)——建議深拷貝
  • 配置對象傳遞給多個組件使用——視情況而定

實現(xiàn)一個簡單的深拷貝函數(shù)(基礎版)

你可以自己寫一個遞歸函數(shù)來處理基本的深拷貝需求:

function deepClone(obj) {   if (typeof obj !== 'object' || obj === null) return obj;    let copy = Array.isArray(obj) ? [] : {};   for (let key in obj) {     if (obj.hasOwnProperty(key)) {       copy[key] = deepClone(obj[key]);     }   }   return copy; }

這個版本雖然簡單,但能應對大部分基礎結構。對于更復雜的場景(如循環(huán)引用、symbol屬性、date對象等),可以考慮使用第三方庫,比如lodash的 cloneDeep。


基本上就這些。理解清楚淺拷貝和深拷貝的區(qū)別,以及何時使用哪種方式,對日常開發(fā)非常重要。

? 版權聲明
THE END
喜歡就支持一下吧
點贊5 分享