推薦答案
實現深拷貝有多種方式,這里提供幾種常見的方法:
方法一:遞歸復制
遞歸復制是一種簡單但是常用的深拷貝實現方式?;舅悸肥潜闅v對象的每個屬性,如果屬性值是一個對象,則遞歸調用該方法進行復制。
function deepClone(obj) {
// 判斷是否是引用類型
if (typeof obj !== 'object' || obj === null) {
return obj;
}
let result;
if (Array.isArray(obj)) {
result = [];
for (let i = 0; i < obj.length; i++) {
result.push(deepClone(obj[i]));
}
} else {
result = {};
for (let key in obj) {
result[key] = deepClone(obj[key]);
}
}
return result;
}
方法二:使用 JSON 對象
如果數據不包含函數、循環(huán)引用等特殊情況,可以使用 JSON 對象的 stringify 和 parse 方法來實現深拷貝。該方法的基本思路是將對象序列化為 JSON 字符串,再將 JSON 字符串反序列化為新的對象。
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
需要注意的是,該方法不能正確處理函數、循環(huán)引用等特殊情況。
方法三:使用第三方庫
如果項目中使用了第三方庫,可以使用該庫提供的深拷貝方法,如 Lodash 庫提供的 cloneDeep 方法。
const _ = require('lodash');
const obj = { a: 1, b: { c: 2 } };
const clonedObj = _.cloneDeep(obj);
使用第三方庫的優(yōu)點是不需要自己實現深拷貝方法,可以直接調用現成的方法。但是需要注意庫的引入和使用方法。
其他答案
-
進行深拷貝的方法:遞歸函數 (推薦使用,項目中使用的更多,更小,更安全)JSON.stringify() 和JSON.parse() ; (不推薦使用,如果遇到Function,Date等類型的變量容易出現一些意料之外的問題),第三方庫lodash的cloneDeep()方法 (就情況而定,如果項目中原先就有l(wèi)odash這個第三方庫,可以使用,否則還是推薦使用遞歸函數。不然成本太高。),JQuery的extend()函數 (推薦在JQuery項目中使用,其他項目依然推薦是用遞歸函數)
-
JavaScript中的對象賦值操作是淺拷貝,即當使用賦值操作符(=)將一個對象賦值給另一個對象時,實際上是將它們的引用指向了同一個對象。如果修改其中一個對象的屬性,另一個對象的屬性也會隨之改變,為了避免這種情況,可以使用深拷貝復制一個對象,即將一個對象及其所有屬性的副本復制到一個新對象中。