深浅拷贝的实现方式以及适用场景(更新版本)

本文详细介绍了JavaScript中的深拷贝和浅拷贝概念,包括它们的区别、实现方式(如递归、JSON序列化、扩展运算符等)、适用场景以及不同方法的优缺点。
摘要由CSDN通过智能技术生成

深拷贝浅拷贝是两种不同的复制对象的方式。

深拷贝会创建一个新的对象,并复制原始对象的所有属性和值,包括嵌套对象。

浅拷贝只会创建一个新的对象,并复制原始对象的引用,而不是值。这意味着对浅拷贝的更改也会影响原始对象。

深拷贝的实现方式

  • 递归:这是最常见的一种实现深拷贝的方式。使用递归可以遍历原始对象的每个属性和值,并创建新的副本。
  • JSON 序列化和反序列化:可以使用 JSON.stringify() 方法将原始对象序列化为 JSON 字符串,然后使用 JSON.parse() 方法将 JSON 字符串反序列化为新的对象。
  • 第三方库:可以使用像 Lodash 这样的第三方库来实现深拷贝。

浅拷贝的实现方式

  • 对象赋值:可以使用 = 运算符将原始对象赋值给新的对象。
  • Object.assign() 方法:可以使用 Object.assign() 方法将原始对象的属性和值复制到新的对象。
  • 扩展运算符:可以使用扩展运算符 (...) 将原始对象的属性和值复制到新的对象。

深浅拷贝的适用场景

  • 需要修改对象副本而不影响原始对象时,应使用深拷贝。例如,在表单编辑场景中,需要对表单数据进行深拷贝,以便在编辑过程中不会影响原始数据。
  • 不需要修改对象副本时,可以使用浅拷贝。例如,在数据传输场景中,可以使用浅拷贝来传输数据,以便节省资源。

以下表格总结了深浅拷贝的主要区别:

特性深拷贝浅拷贝
复制方式创建新的对象并复制所有属性和值创建新的对象并复制引用
嵌套对象也会被复制不会被复制
适用场景需要修改对象副本而不影响原始对象不需要修改对象副本

示例

JavaScript

// 深拷贝
const originalObject = {
  name: "John Doe",
  age: 30,
  address: {
    street: "123 Main Street",
    city: "New York",
    state: "NY",
    zip: "10001",
  },
};

const deepCopy = JSON.parse(JSON.stringify(originalObject));

deepCopy.name = "Jane Doe";
deepCopy.address.city = "Los Angeles";

console.log(originalObject); // { name: "John Doe", age: 30, address: { street: "123 Main Street", city: "New York", state: "NY", zip: "10001" } }
console.log(deepCopy); // { name: "Jane Doe", age: 30, address: { street: "123 Main Street", city: "Los Angeles", state: "NY", zip: "10001" } }

// 浅拷贝
const shallowCopy = Object.assign({}, originalObject);

shallowCopy.name = "Jane Doe";
shallowCopy.address.city = "Los Angeles";

console.log(originalObject); // { name: "Jane Doe", age: 30, address: { street: "123 Main Street", city: "Los Angeles", state: "NY", zip: "10001" } }
console.log(shallowCopy); // { name: "Jane Doe", age: 30, address: { street: "123 Main Street", city: "Los Angeles", state: "NY", zip: "10001" } }

 

深度拷贝的其它实现方法

1. 使用 ES6 的扩展运算符 (...)

        

JavaScript

const originalObject = {
  name: "John Doe",
  age: 30,
  address: {
    street: "123 Main Street",
    city: "New York",
    state: "NY",
    zip: "10001",
  },
};

const deepCopy = {...originalObject};

deepCopy.name = "Jane Doe";
deepCopy.address.city = "Los Angeles";

console.log(originalObject); // { name: "John Doe", age: 30, address: { street: "123 Main Street", city: "New York", state: "NY", zip: "10001" } }
console.log(deepCopy); // { name: "Jane Doe", age: 30, address: { street: "123 Main Street", city: "Los Angeles", state: "NY", zip: "10001" } }

2. 使用 Object.create() 方法 

JavaScript

const originalObject = {
  name: "John Doe",
  age: 30,
  address: {
    street: "123 Main Street",
    city: "New York",
    state: "NY",
    zip: "10001",
  },
};

const deepCopy = Object.create(originalObject);

deepCopy.name = "Jane Doe";
deepCopy.address.city = "Los Angeles";

console.log(originalObject); // { name: "John Doe", age: 30, address: { street: "123 Main Street", city: "New York", state: "NY", zip: "10001" } }
console.log(deepCopy); // { name: "Jane Doe", age: 30, address: { street: "123 Main Street", city: "Los Angeles", state: "NY", zip: "10001" } }

3. 使用 Lodash 库

JavaScript

const originalObject = {
  name: "John Doe",
  age: 30,
  address: {
    street: "123 Main Street",
    city: "New York",
    state: "NY",
    zip: "10001",
  },
};

const deepCopy = _.cloneDeep(originalObject);

deepCopy.name = "Jane Doe";
deepCopy.address.city = "Los Angeles";

console.log(originalObject); // { name: "John Doe", age: 30, address: { street: "123 Main Street", city: "New York", state: "NY", zip: "10001" } }
console.log(deepCopy); // { name: "Jane Doe", age: 30, address: { street: "123 Main Street", city: "Los Angeles", state: "NY", zip: "10001" } }

每种方法都有其优缺点,应根据具体情况选择合适的方法。

以下是一些比较:

方法优点缺点
递归通用性强效率低,容易造成栈溢出
JSON 序列化和反序列化效率高不支持循环引用
第三方库方便易用需要引入第三方库
ES6 扩展运算符简洁易用不支持 Symbol 类型
Object.create() 方法效率高不支持 Symbol 类型
Lodash 库功能强大需要引入第三方库

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值