返回

深浅拷贝之微妙且重要

前端

细微差别,大有不同

在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。然后,我们修改了shallowCopyname属性和friends数组的第一个元素。最后,我们打印了originalshallowCopy,可以看到它们都受到了修改。

深拷贝复制所有层级

深拷贝复制对象或数组的所有层级,包括嵌套属性或元素。如果嵌套属性或元素也是对象或数组,它们将被递归地复制到新的对象或数组中。

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。然后,我们修改了deepCopyname属性和friends数组的第一个元素。最后,我们打印了originaldeepCopy,可以看到只有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()函数创建了浅拷贝和深拷贝。然后,我们修改了shallowCopyname属性和friends数组的第一个元素。最后,我们打印了originalshallowCopydeepCopy,可以看到只有shallowCopy受到了修改。