我不知道如何在 JS/TS 中創(chuàng)建深度克隆
在JavaScript和TypeScript開發(fā)中,對象的深度克隆是一個常見但容易被誤解的話題。本文將探討幾種常用的克隆方法,揭示它們的局限性,并介紹真正有效的深度克隆技術(shù)。
常見誤區(qū):展開運算符和Object.create()
許多開發(fā)者習(xí)慣使用展開運算符{...}或Object.create()來克隆對象,但這些方法實際上只能進行淺拷貝。
展開運算符的局限性:
const original = { name: "John", address: { city: "New York" } };
const clone = { ...original };
clone.address.city = "Los Angeles";
console.log(original.address.city); // 輸出: "Los Angeles"Object.create()的問題:
const original = { name: "John", address: { city: "New York" } };
const clone = Object.create(original);
clone.address.city = "Chicago";
console.log(original.address.city); // 輸出: "Chicago"這兩種方法都無法實現(xiàn)真正的深度克隆,因為它們只復(fù)制了對象的頂層屬性。
JSON.parse(JSON.stringify()):簡單而有效
對于簡單對象,JSON.parse(JSON.stringify())是一個有效的深度克隆方法:
const original = { name: "John", address: { city: "New York" } };
const clone = JSON.parse(JSON.stringify(original));
clone.address.city = "San Francisco";
console.log(original.address.city); // 輸出: "New York"然而,這種方法也有局限性。它無法處理函數(shù)、undefined、Infinity、NaN、正則表達式、Map和Set等復(fù)雜數(shù)據(jù)類型。
lodash.deepClone:全面而強大
對于需要處理復(fù)雜數(shù)據(jù)結(jié)構(gòu)的場景,lodash.deepClone是一個更全面的解決方案:
import _ from 'lodash';
const original = {
  name: "John",
  address: { city: "New York" },
  skills: new Set(["JavaScript", "TypeScript"]),
  greet: function() { console.log("Hello!"); }
};
const clone = _.cloneDeep(original);
clone.address.city = "Boston";
clone.skills.add("React");
console.log(original.address.city); // 輸出: "New York"
console.log(original.skills.has("React")); // 輸出: falselodash.deepClone能夠正確處理嵌套對象、數(shù)組、函數(shù),以及特殊的數(shù)據(jù)結(jié)構(gòu)如Set和Map。
性能考慮
在性能方面,JSON.parse(JSON.stringify())通常對簡單對象更快,而lodash.deepClone對復(fù)雜結(jié)構(gòu)更可靠但速度較慢。
// 性能測試示例
const simpleObject = { a: 1, b: 2, c: 3 };
const complexObject = { /* 復(fù)雜的嵌套結(jié)構(gòu) */ };
console.time('JSON Simple');
JSON.parse(JSON.stringify(simpleObject));
console.timeEnd('JSON Simple');
console.time('Lodash Simple');
_.cloneDeep(simpleObject);
console.timeEnd('Lodash Simple');
console.time('JSON Complex');
JSON.parse(JSON.stringify(complexObject));
console.timeEnd('JSON Complex');
console.time('Lodash Complex');
_.cloneDeep(complexObject);
console.timeEnd('Lodash Complex');結(jié)論
在JavaScript和TypeScript中實現(xiàn)無突變的深度克隆可能比想象的更復(fù)雜。展開運算符和Object.create()雖然常用,但不適合深度克隆。JSON.parse(JSON.stringify())對于簡單對象是一個快速有效的解決方案,而lodash.deepClone則是處理復(fù)雜數(shù)據(jù)結(jié)構(gòu)的理想選擇。
理解這些方法的優(yōu)缺點對于選擇合適的克隆策略至關(guān)重要。在實際開發(fā)中,應(yīng)根據(jù)具體需求和數(shù)據(jù)結(jié)構(gòu)的復(fù)雜性來選擇適當(dāng)?shù)纳疃瓤寺》椒?。通過掌握這些技巧,開發(fā)者可以更有效地處理對象克隆,提高代碼的健壯性和可維護性。















 
 
 







 
 
 
 