JavaScript深拷贝的几种情况总结
在 JavaScript 中,对于对象的赋值,常常会遇到浅拷贝和深拷贝的问题。浅拷贝只复制对象的引用,而深拷贝则是复制对象的值。这篇文章将总结 JavaScript 中深拷贝的几种情况以及对应的实现方法。
基本数据类型
字符串、数值、布尔类型(string, number, boolean)
基本数据类型的深拷贝非常简单,只需要把值赋给新的变量即可。
let str = 'hello';
let num = 123;
let bool = true;
let str2 = str;
let num2 = num;
let bool2 = bool;
以上代码中,str2
、num2
、bool2
分别是 str
、num
、bool
的深拷贝。
null 和 undefined
null
和 undefined
是 JavaScript 中的特殊值,它们并不是对象,也不是基本数据类型,因此没有值可以深拷贝。
引用数据类型
数组(Array)
对于数组的深拷贝,可以使用 Array.from()
或者 spread operator
。
let arr = [1, 2, 3];
let arr2 = Array.from(arr);
let arr3 = [...arr];
以上代码中,arr2
和 arr3
分别是 arr
的深拷贝。
对象(Object)
对于对象的深拷贝,可以使用 JSON.parse(JSON.stringify())
,但是要注意该方法会忽略对象中的函数、undefined
和 symbol
等。
let obj = {
name: 'Alice',
age: 18,
children: [
{
name: 'Bob',
age: 1,
},
{
name: 'Charlie',
age: 2,
},
],
};
let obj2 = JSON.parse(JSON.stringify(obj));
以上代码中,obj2
是 obj
的深拷贝。
自定义对象
对于自定义对象,可以通过递归实现深拷贝。
function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
let result;
if (Array.isArray(obj)) {
result = [];
} else {
result = {};
}
for (let key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
result[key] = deepCopy(obj[key]);
}
}
return result;
}
let obj = {
name: 'Alice',
age: 18,
children: [
{
name: 'Bob',
age: 1,
},
{
name: 'Charlie',
age: 2,
},
],
};
let obj2 = deepCopy(obj);
以上代码中,obj2
是 obj
的深拷贝。
示例说明
示例一
let obj = {
name: 'Alice',
age: 18,
friends: {
name: 'Bob',
age: 19,
},
};
let obj2 = JSON.parse(JSON.stringify(obj));
obj2.friends.age = 20;
console.log(obj); // { name: 'Alice', age: 18, friends: { name: 'Bob', age: 19 } }
console.log(obj2); // { name: 'Alice', age: 18, friends: { name: 'Bob', age: 20 } }
在以上代码中,obj
和 obj2
都是对象,通过 JSON.parse(JSON.stringify())
实现深拷贝。但是,当我们改变 obj2.friends.age
的值时,obj
的值不会受到影响,这说明 JSON.parse(JSON.stringify())
并不是完全的深拷贝。
示例二
let arr = [
{
name: 'Alice',
age: 18,
},
{
name: 'Bob',
age: 19,
},
];
let arr2 = Array.from(arr);
arr2[0].age = 20;
console.log(arr); // [ { name: 'Alice', age: 18 }, { name: 'Bob', age: 19 } ]
console.log(arr2); // [ { name: 'Alice', age: 20 }, { name: 'Bob', age: 19 } ]
在以上代码中,arr
和 arr2
都是数组,通过 Array.from()
实现深拷贝。但是,当我们改变 arr2[0].age
的值时,arr
的值也会发生变化,这说明 Array.from()
并不是完全的深拷贝。
注意以上两个示例在深拷贝过程中的缺陷,应该根据具体情况选择合适的深拷贝方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:javascript深拷贝的几种情况总结 - Python技术站