JavaScript 中的深拷贝与浅拷贝

在 JavaScript 中,对象的复制通常分为两种类型:深拷贝和浅拷贝。这两种拷贝方式在处理对象和数组时有不同的影响,因此在开发中选择适当的拷贝方式非常重要。让我们深入了解这两种拷贝方式以及它们的区别。

1. 浅拷贝

浅拷贝是指复制一个对象,创建一个新对象,但仅复制原始对象的第一层结构。换句话说,如果原始对象包含引用类型(例如对象或数组),则浅拷贝只会复制引用而不会复制引用指向的对象本身。

1.1 使用 Object.assign()

js 复制代码
const originalObject = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, originalObject);

console.log(shallowCopy);
// 输出: { a: 1, b: { c: 2 } }

console.log(originalObject.b === shallowCopy.b);
// 输出: true

1.2 使用展开运算符(Spread Operator)

js 复制代码
const originalObject = { a: 1, b: { c: 2 } };
const shallowCopy = { ...originalObject };

console.log(shallowCopy);
// 输出: { a: 1, b: { c: 2 } }

console.log(originalObject.b === shallowCopy.b);
// 输出: true

浅拷贝的缺点在于,如果原始对象的属性值是引用类型,那么浅拷贝后的对象仍然会共享这些引用类型的值。

2. 深拷贝

深拷贝是指创建一个新对象,并递归地复制原始对象的所有嵌套属性,包括引用类型。这确保了原始对象和拷贝后的对象是完全独立的,不共享任何引用类型的值。

2.1 使用递归实现深拷贝

js 复制代码
function deepCopy(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return obj; // 非对象或 null 直接返回
  }

  let copy = Array.isArray(obj) ? [] : {};

  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepCopy(obj[key]);
    }
  }

  return copy;
}

const originalObject = { a: 1, b: { c: 2 } };
const deepCopyObject = deepCopy(originalObject);

console.log(deepCopyObject);
// 输出: { a: 1, b: { c: 2 } }

console.log(originalObject.b === deepCopyObject.b);
// 输出: false

2.2 使用 JSON 序列化与反序列化

js 复制代码
const originalObject = { a: 1, b: { c: 2 } };
const deepCopyObject = JSON.parse(JSON.stringify(originalObject));

console.log(deepCopyObject);
// 输出: { a: 1, b: { c: 2 } }

console.log(originalObject.b === deepCopyObject.b);
// 输出: false

需要注意的是,使用 JSON 序列化和反序列化的方法有一些限制,例如无法处理包含函数、正则表达式等特殊对象。

手写一个浅拷贝

js 复制代码
function shalldowCopy(obj) {
  if (typeof obj !== 'object' || obj == null) return  //只拷贝引用类型
  let objCopy = obj instanceof Array ? [] : {}
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      objCopy[key] = obj[key]
    }
  }
  return objCopy
}

总结

选择深拷贝还是浅拷贝取决于你的需求。浅拷贝通常足够满足简单的场景,但在涉及复杂嵌套结构、共享状态或需要保留原始对象与拷贝对象完全独立的情况下,深拷贝是更安全的选择。在实际开发中,根据具体情况选择合适的拷贝方式是非常重要的。

相关推荐
p***h64322 分钟前
JavaScript在Node.js中的异步编程
开发语言·javascript·node.js
N***738537 分钟前
Vue网络编程详解
前端·javascript·vue.js
q***38512 小时前
TypeScript 与后端开发Node.js
javascript·typescript·node.js
Nan_Shu_6142 小时前
学习:Sass
javascript·学习·es6
WYiQIU3 小时前
面了一次字节前端岗,我才知道何为“造火箭”的极致!
前端·javascript·vue.js·react.js·面试
qq_316837753 小时前
uniapp 观察列表每个元素的曝光时间
前端·javascript·uni-app
小夏同学呀3 小时前
在 Vue 2 中实现 “点击下载条码 → 打开新窗口预览 → 自动唤起浏览器打印” 的功能
前端·javascript·vue.js
芳草萋萋鹦鹉洲哦3 小时前
【vue】导航栏变动后刷新router的几种方法
前端·javascript·vue.js
zero13_小葵司3 小时前
JavaScript性能优化系列(八)弱网环境体验优化 - 8.3 数据预加载与缓存:提前缓存关键数据
javascript·缓存·性能优化
努力学算法的蒟蒻3 小时前
day20(11.21)——leetcode面试经典150
面试