JavaScript 中实现拷贝的方法有多种,具体使用哪种方法取决于你要拷贝的数据类型和拷贝的需求。以下是几种常见的拷贝方法:
浅拷贝(Shallow Copy):
- Object.assign():用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。注意,Object.assign() 只会拷贝源对象自身的属性,而不会拷贝其原型链上的属性。
function shallowCopy(obj) {
return Object.assign({}, obj);
}
let original = { a: 1, b: { c: 2 } };
let copy = shallowCopy(original);
- 扩展运算符 (…):也称为 rest 运算符,可以用于创建一个新对象,该对象是通过浅拷贝源对象的所有可枚举属性创建的。
function shallowCopy(obj) {
return { ...obj };
}
let original = { a: 1, b: { c: 2 } };
let copy = shallowCopy(original);
- for…in 或 for…of 循环
function shallowCopy(obj) {
let clone = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = obj[key];
}
}
return clone;
}
// 或者使用for...of循环(仅适用于可迭代对象)
function shallowCopy(obj) {
let clone = {};
for (let [key, value] of Object.entries(obj)) {
clone[key] = value;
}
return clone;
}
let original = { a: 1, b: { c: 2 } };
let copy = shallowCopy(original);
- Array.slice() 和 Array.concat():用于拷贝数组的部分或全部元素,但只能实现浅拷贝。
const arr1 = [1, 2, 3];
const arr2 = arr1.slice();
console.log(arr2); // [1, 2, 3]
const arr1 = [1, 2, 3];
const arr2 = arr1.concat();
console.log(arr2); // [1, 2, 3]
- Array.from():将类数组对象或可迭代对象转换为数组,可以用于实现浅拷贝。
深拷贝(Deep Copy):
- JSON.parse(JSON.stringify()):将对象转换为 JSON 字符串,然后再将 JSON 字符串转换回对象。这种方法能够实现深拷贝,但是有一些限制,例如无法拷贝函数、正则表达式、循环引用等。
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = JSON.parse(JSON.stringify(obj1));
obj2.b.c = 3;
console.log(obj1); // { a: 1, b: { c: 2 } }
console.log(obj2); // { a: 1, b: { c: 3 } }
- 递归复制:通过递归遍历对象的所有属性,并将它们复制到新的对象中来实现深拷贝。这种方法可以自定义处理复杂对象,但需要谨防循环引用导致的死循环。
function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj; // 非对象或 null 直接返回
}
const newObj = Array.isArray(obj) ? [] : {}; // 创建新的对象或数组
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepCopy(obj[key]); // 递归调用深拷贝
}
}
return newObj;
}
使用示例:
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = deepCopy(obj1);
obj2.b.c = 3;
console.log(obj1); // { a: 1, b: { c: 2 } }
console.log(obj2); // { a: 1, b: { c: 3 } }
- 使用第三方库:
有一些第三方库(如 lodash、underscore 等)提供了深拷贝的方法,可以直接调用这些方法来实现深拷贝。
const _ = require('lodash');
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = _.cloneDeep(obj1);
obj2.b.c = 3;
console.log(obj1); // { a: 1, b: { c: 2 } }
console.log(obj2); // { a: 1, b: { c: 3 } }