返回

浅显易懂,JavaScript 深度和浅度拷贝详尽指南

前端

JavaScript 中的深拷贝和浅拷贝是两个重要的概念,它们决定了在复制对象或数组时,是否保留原有数据结构及其子元素的引用。理解这两者的区别至关重要,否则可能会导致代码出现意料之外的结果。

什么是深拷贝和浅拷贝?

浅拷贝会在内存中创建一个新对象,但新对象仅包含对原始对象中引用类型元素的引用。换句话说,浅拷贝不会复制原始对象中嵌套的对象或数组,而是只是复制它们的引用。因此,当修改新对象中对这些嵌套元素的引用时,原始对象也会受到影响。

而深拷贝则会在内存中创建一个新对象,并复制原始对象中所有元素的值,包括基本类型和引用类型。这意味着新对象与原始对象完全独立,修改新对象中的元素不会影响原始对象。

什么导致了深拷贝和浅拷贝的不同?

JavaScript 中存在基本类型和引用类型。基本类型包括数字、字符串和布尔值,它们在内存中存储实际值。引用类型包括对象和数组,它们在内存中存储对实际值的引用。

当复制基本类型值时,JavaScript 会创建一个新值,并把它放在一个新的变量的内存地。因此,修改新值不会影响原始值。

当复制引用类型值时,JavaScript 不会创建一个新值,而只会创建一个对原始值的引用。因此,修改新值也会影响原始值。

深拷贝和浅拷贝的示例

以下是浅拷贝的示例:

const obj1 = {
  name: 'John',
  age: 30,
  address: {
    street: 'Main Street',
    city: 'New York',
    state: 'NY',
  },
};

const obj2 = obj1;

obj2.name = 'Jane';
obj2.address.city = 'Los Angeles';

console.log(obj1); // { name: 'Jane', age: 30, address: { street: 'Main Street', city: 'Los Angeles', state: 'NY' } }

在上面的示例中,obj2obj1 的浅拷贝。当修改 obj2 中的属性时,obj1 中的相应属性也会受到影响。

以下是深拷贝的示例:

const obj1 = {
  name: 'John',
  age: 30,
  address: {
    street: 'Main Street',
    city: 'New York',
    state: 'NY',
  },
};

const obj2 = JSON.parse(JSON.stringify(obj1));

obj2.name = 'Jane';
obj2.address.city = 'Los Angeles';

console.log(obj1); // { name: 'John', age: 30, address: { street: 'Main Street', city: 'New York', state: 'NY' } }

在上面的示例中,obj2obj1 的深拷贝。当修改 obj2 中的属性时,obj1 中的相应属性不会受到影响。

深拷贝和浅拷贝的使用场景

浅拷贝通常用于需要共享数据结构的情况,例如在组件之间传递数据时。而深拷贝通常用于需要隔离数据结构的情况,例如在存储敏感数据时。

总结

深拷贝和浅拷贝是 JavaScript 中两个重要的概念,理解它们的区别对于编写健壮、可靠的代码至关重要。在复制对象或数组时,应根据具体情况选择合适的拷贝方式。