返回

JSON 数据格式 —— 深拷贝和浅拷贝剖析

前端

JSON 简介

JSON(JavaScript Object Notation)是一种轻量级的数据格式,常用于前后端数据交互。它使用文本表示对象,便于计算机解析和生成。JSON 具有良好的可读性和可写性,并且易于在不同的编程语言和平台之间传输。

JSON 的基本语法与 JavaScript 对象非常相似,由键值对组成,键是字符串,值可以是字符串、数字、布尔值、数组、对象或 null。JSON 对象用大括号 {} 括起来,键值对之间用冒号 : 分隔,键和值之间用逗号 , 分隔。例如:

{
  "name": "John Doe",
  "age": 30,
  "occupation": "Software Engineer"
}

深拷贝与浅拷贝

在 JavaScript 中,对象是引用类型。这意味着当复制一个对象时,实际复制的是对该对象的引用,而不是对象本身。这种复制方式称为浅拷贝(shallow copy)。浅拷贝只复制对象本身的属性,不复制子对象。

深拷贝(deep copy)则不同,它不仅复制对象本身的属性,还递归复制子对象。这意味着深拷贝后的新对象与原始对象完全独立,即使修改新对象也不会影响原始对象。

浅拷贝

浅拷贝可以通过简单的赋值运算符(=)或 Object.assign() 方法实现。例如:

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

const obj2 = obj1; // 浅拷贝

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

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

可以看到,对 obj2 的修改也影响了 obj1,因为这两个对象实际上指向同一个内存地址。

深拷贝

深拷贝可以通过 JSON.stringify() 和 JSON.parse() 方法实现。例如:

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

const obj2 = JSON.parse(JSON.stringify(obj1)); // 深拷贝

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

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

可以看到,对 obj2 的修改并没有影响 obj1,因为这两个对象是独立的。

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

深拷贝和浅拷贝在不同的场景下都有各自的应用。

浅拷贝的应用场景

  • 当需要复制一个对象,但不需要修改子对象时,可以使用浅拷贝。例如,在将对象作为函数参数传递时,就可以使用浅拷贝。
  • 当需要复制一个对象,并且希望修改子对象时,可以使用浅拷贝。例如,在克隆一个对象并对其进行修改时,就可以使用浅拷贝。

深拷贝的应用场景

  • 当需要复制一个对象,并且希望确保新对象与原始对象完全独立时,可以使用深拷贝。例如,在将对象存储到数据库或缓存中时,就可以使用深拷贝。
  • 当需要复制一个对象,并且希望确保新对象不受原始对象的影响时,可以使用深拷贝。例如,在将对象发送到另一个进程或线程时,就可以使用深拷贝。

总结

JSON 是一种轻量级的数据格式,常用于前后端数据交互。它使用文本表示对象,便于计算机解析和生成。JSON 具有良好的可读性和可写性,并且易于在不同的编程语言和平台之间传输。

在 JavaScript 中,对象是引用类型。这意味着当复制一个对象时,实际复制的是对该对象的引用,而不是对象本身。浅拷贝只复制对象本身的属性,不复制子对象。深拷贝则不仅复制对象本身的属性,还递归复制子对象。

深拷贝和浅拷贝在不同的场景下都有各自的应用。浅拷贝适用于需要复制一个对象,但不需要修改子对象的情况。深拷贝适用于需要复制一个对象,并且希望确保新对象与原始对象完全独立的情况。