一行代碼解決深拷貝問題,JavaScript 新特性解析
深拷貝是JavaScript里一個常見而又棘手的問題,長久以來,我們不得不依賴各種自定義方法或第三方庫來解決這一問題。大多數(shù)人都會使用JSON.parse(JSON.stringify(obj))這種方式,但它存在眾多限制。好消息是,現(xiàn)代JavaScript為我們帶來了原生的解決方案:structuredClone()方法。
深拷貝的傳統(tǒng)解決方案及其問題
回顧一下,我們通常使用以下方法來實現(xiàn)深拷貝:
這些方法各有缺點:
- JSON方法的局限性: 無法處理函數(shù)/Symbol類型/undefined值/循環(huán)引用,無法正確處理Date、RegExp、Map、Set等特殊對象,會丟失原型鏈
- 自定義遞歸函數(shù): 實現(xiàn)復(fù)雜,容易出錯,通常需要額外處理各種特殊類型,性能不一定理想
- 第三方庫: 增加項目依賴,增加打包體積
structuredClone:現(xiàn)代JavaScript的深拷貝解決方案
2022年,WHATWG HTML標(biāo)準引入了structuredClone()方法,現(xiàn)在它已被所有主流瀏覽器和Node.js支持。這個方法提供了一種高效、標(biāo)準化的方式來創(chuàng)建復(fù)雜JavaScript對象的深拷貝。
基本用法
使用structuredClone()非常簡單:
就是這么簡單!一行代碼,無需任何額外的庫或復(fù)雜的遞歸函數(shù)。
structuredClone的優(yōu)勢
- 內(nèi)置于JavaScript引擎,無需外部依賴
- 處理循環(huán)引用,不會像JSON方法那樣拋出錯誤
- 正確處理大多數(shù)JavaScript內(nèi)置類型,包括: Date對象/RegExp對象/Map和Set/ArrayBuffer和TypedArrays/Blob對象/File對象/ImageData對象/嵌套的復(fù)雜對象結(jié)構(gòu)
處理循環(huán)引用的示例
支持的數(shù)據(jù)類型詳解
structuredClone()支持的類型遠超JSON方法:
const original = {
// 原始類型
string: 'Hello',
number: 123,
boolean: true,
null: null,
undefined: undefined, // JSON會丟失,structuredClone保留
// 日期對象 (JSON會轉(zhuǎn)為字符串,structuredClone保持為Date對象)
date: newDate('2023-06-15'),
// 正則表達式 (JSON會轉(zhuǎn)為空對象,structuredClone保持為RegExp對象)
regex: /pattern/g,
// 集合類型
map: newMap([['key', 'value']]),
set: newSet([1, 2, 3]),
// 二進制數(shù)據(jù)
arrayBuffer: newUint8Array([1, 2, 3]).buffer,
typedArray: newUint8Array([1, 2, 3]),
// 嵌套數(shù)組和對象
array: [1, 2, { nested: true }],
object: { nested: { deep: true } }
};
const clone = structuredClone(original);
// 驗證類型保持一致
console.log(clone.dateinstanceofDate); // true
console.log(clone.regexinstanceofRegExp); // true
console.log(clone.mapinstanceofMap); // true
console.log(clone.setinstanceofSet); // true
console.log(clone.arrayBufferinstanceofArrayBuffer); // true
console.log(clone.typedArrayinstanceofUint8Array); // true
structuredClone的局限性
雖然structuredClone()解決了大多數(shù)深拷貝問題,但它仍有一些限制:
- 不支持函數(shù):與JSON方法一樣,函數(shù)不會被克隆
- 不克隆原型鏈:克隆的對象會丟失原始對象的原型鏈
- 不支持DOM節(jié)點
- 不支持Error對象
structuredClone() 是JavaScript生態(tài)系統(tǒng)中的一個重要進步,它為常見的深拷貝問題提供了一個簡單、高效且標(biāo)準化的解決方案。雖然它有一些限制,但在大多數(shù)常見場景中,它都是深拷貝的最佳選擇。目前,structuredClone() 已被所有主流瀏覽器支持。