深浅拷贝之微妙且重要
2024-01-21 18:27:33
细微差别,大有不同
在JavaScript中,变量可以存储两种基本类型:原始类型和引用类型。原始类型包括:字符串、数字、布尔值、undefined和null。引用类型包括:对象、数组和函数。
浅拷贝只复制最外层
浅拷贝只复制对象或数组最外层的值,不会复制它们的嵌套属性或元素。如果嵌套属性或元素也是对象或数组,它们将仍然指向原来的内存地址。
const original = {
name: 'Alice',
age: 20,
friends: ['Bob', 'Carol'],
};
const shallowCopy = { ...original };
shallowCopy.name = 'Bob';
shallowCopy.friends[0] = 'Dave';
console.log(original);
// { name: 'Bob', age: 20, friends: [ 'Dave', 'Carol' ] }
console.log(shallowCopy);
// { name: 'Bob', age: 20, friends: [ 'Dave', 'Carol' ] }
在上面的例子中,我们创建了一个对象original
,然后使用扩展运算符...
创建了一个浅拷贝shallowCopy
。然后,我们修改了shallowCopy
的name
属性和friends
数组的第一个元素。最后,我们打印了original
和shallowCopy
,可以看到它们都受到了修改。
深拷贝复制所有层级
深拷贝复制对象或数组的所有层级,包括嵌套属性或元素。如果嵌套属性或元素也是对象或数组,它们将被递归地复制到新的对象或数组中。
const original = {
name: 'Alice',
age: 20,
friends: ['Bob', 'Carol'],
};
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.name = 'Bob';
deepCopy.friends[0] = 'Dave';
console.log(original);
// { name: 'Alice', age: 20, friends: [ 'Bob', 'Carol' ] }
console.log(deepCopy);
// { name: 'Bob', age: 20, friends: [ 'Dave', 'Carol' ] }
在上面的例子中,我们创建了一个对象original
,然后使用JSON.parse()
和JSON.stringify()
函数创建了一个深拷贝deepCopy
。然后,我们修改了deepCopy
的name
属性和friends
数组的第一个元素。最后,我们打印了original
和deepCopy
,可以看到只有deepCopy
受到了修改。
深浅拷贝何时使用?
浅拷贝通常用于不需要修改嵌套属性或元素的情况下。例如,如果我们只想创建一个对象或数组的副本以便在内存中使用,浅拷贝就足够了。
深拷贝通常用于需要修改嵌套属性或元素的情况下。例如,如果我们想创建一个对象或数组的副本以便在内存中修改,而不想影响原始对象或数组,就需要使用深拷贝。
使用第三方库
如果你不想自己编写深拷贝或浅拷贝函数,可以使用第三方库。例如,你可以使用Lodash库中的_.clone()
函数或_.cloneDeep()
函数。
const original = {
name: 'Alice',
age: 20,
friends: ['Bob', 'Carol'],
};
const shallowCopy = _.clone(original);
const deepCopy = _.cloneDeep(original);
shallowCopy.name = 'Bob';
shallowCopy.friends[0] = 'Dave';
console.log(original);
// { name: 'Alice', age: 20, friends: [ 'Bob', 'Carol' ] }
console.log(shallowCopy);
// { name: 'Bob', age: 20, friends: [ 'Dave', 'Carol' ] }
console.log(deepCopy);
// { name: 'Alice', age: 20, friends: [ 'Bob', 'Carol' ] }
在上面的例子中,我们使用了Lodash库的_.clone()
函数和_.cloneDeep()
函数创建了浅拷贝和深拷贝。然后,我们修改了shallowCopy
的name
属性和friends
数组的第一个元素。最后,我们打印了original
、shallowCopy
和deepCopy
,可以看到只有shallowCopy
受到了修改。