JavaScript 如何複製一個對象?淺拷貝可以複製出原始值屬性,但是對於引用值屬性僅僅複製了一份引用。利用遞歸對每個引用值屬性的屬性進行複製,這種方式稱之為深拷貝 ...
JavaScript 對象拷貝
JavaScript 如何複製一個對象?淺拷貝可以複製出原始值屬性,但是對於引用值屬性僅僅複製了一份引用。利用遞歸對每個引用值屬性的屬性進行複製,這種方式稱之為深拷貝
問題引入
var person1 = {
name: '張三',
age: "22"
}
var person2 = person1;
我們希望拷貝一份 person1 的屬性給 person2,賦值是最簡單的做法,但是這並不是我們想要的結果。 因為這僅僅是將 person1、person2 指向了同一對象,修改其一,會相互影響
對象淺拷貝
var person1 = {
name: '張三',
age: 22,
son: {
name: '張小三',
age: 1
}
}
var person2 = {};
for (var key in person1) {
person2[key] = person1[key];
}
迴圈將 person1 的屬性取出賦值給 person2,對於原始類型屬性,不相互影響,可以成功拷貝,但是對於引用類型的屬性,如 person2.son 和 person1.son 指向了同一對象,修改其一,會相互影響
如果不需要 person1 原型鏈上的屬性,賦值時使用 hasOwnProperty() 判斷
對象深拷貝
淺拷貝複製引用值只是將引用指向這個值,並不是複製了一份,修改其一,會相互影響。我們可以將屬性中的引用值也迴圈其屬性,複製到目標對象的屬性。這種需求適合遞歸
var person1 = {
name: '張三',
age: 30,
son: {
first: {
name: '小一',
age: 3
}
}
}
function deepClone(origin) {
var target = {};
var toStr = Object.prototype.toString;
for (var key in origin) {
if (!origin.hasOwnProperty(key)) continue;
if (typeof(origin[key]) === 'object' && origin[key] !== null) {
if (toStr.call(origin[key]) === "[objcet Array]") {
target[key] = [];
} else {
target[key] = {};
}
target[key] = deepClone(origin[key]);
} else {
target[key] = origin[key];
}
}
return target;
}
var person2 = deepClone(person1);
person2.son.sencond = {
name: '小二',
age: 2
}
console.log(person2);
console.log(person1);
person2 含有 person1 的所有屬性,對於原始值屬性進行修改,不會相互影響