JavaScript如何深拷贝一个对象或数组?JSON.parse (JSON.stringify ()) 这种方法有什么局限性?

embedded/2025/2/25 4:58:11/

如何深拷贝一个对象或数组

啥是深拷贝

深拷贝就像是给一个东西(对象或者数组)做了个完全一样的“克隆体”。这个“克隆体”和原来的东西没有任何关联,你对“克隆体”做任何修改,都不会影响到原来的东西,反过来也一样。

简单方法:JSON.parse(JSON.stringify())

这是一种比较简单的深拷贝方法。可以把它想象成,先把要拷贝的对象或者数组“翻译”成 JSON 格式的字符串,这个字符串就像是一个“蓝图”,然后再根据这个“蓝图”重新构建一个新的对象或者数组。

代码示例

javascript">// 定义一个对象
const originalObj = {name: '张三',age: 25,hobbies: ['篮球', '阅读']
};// 使用 JSON.parse(JSON.stringify()) 进行深拷贝
const clonedObj = JSON.parse(JSON.stringify(originalObj));// 修改克隆对象的属性
clonedObj.name = '李四';
clonedObj.hobbies.push('游泳');console.log(originalObj); 
// 输出: { name: '张三', age: 25, hobbies: [ '篮球', '阅读' ] }
console.log(clonedObj); 
// 输出: { name: '李四', age: 25, hobbies: [ '篮球', '阅读', '游泳' ] }

从上面的代码可以看到,修改克隆对象的属性,原来的对象并没有受到影响。

手动实现深拷贝(递归方法)

手动实现深拷贝就是自己写代码来创建“克隆体”。对于对象和数组,需要递归地处理它们的每一个属性或者元素。

代码示例

javascript">function deepClone(target) {// 如果目标不是对象或者数组,直接返回if (typeof target!== 'object' || target === null) {return target;}let clone;// 判断是数组还是对象if (Array.isArray(target)) {clone = [];// 遍历数组元素for (let i = 0; i < target.length; i++) {// 递归调用深拷贝函数clone[i] = deepClone(target[i]);}} else {clone = {};// 遍历对象属性for (let key in target) {if (target.hasOwnProperty(key)) {// 递归调用深拷贝函数clone[key] = deepClone(target[key]);}}}return clone;
}// 定义一个对象
const original = {name: '王五',info: {address: '北京'}
};// 使用自定义深拷贝函数
const cloned = deepClone(original);// 修改克隆对象的属性
cloned.info.address = '上海';console.log(original); 
// 输出: { name: '王五', info: { address: '北京' } }
console.log(cloned); 
// 输出: { name: '王五', info: { address: '上海' } }

这个自定义的 deepClone 函数会检查目标是对象还是数组,然后递归地处理每一个属性或者元素,确保“克隆体”和原来的东西完全独立。

JSON.parse(JSON.stringify()) 方法的局限性

1. 无法处理函数和正则表达式

JSON.stringify() 会忽略对象中的函数和正则表达式,因为 JSON 格式不支持这些类型。这就好比在画“蓝图”的时候,把函数和正则表达式这些“特殊零件”给漏掉了。

代码示例

javascript">const obj = {name: '赵六',sayHello: function() {console.log('你好');},reg: /abc/
};const clonedObj = JSON.parse(JSON.stringify(obj));console.log(clonedObj); 
// 输出: { name: '赵六' }

可以看到,sayHello 函数和 reg 正则表达式都没有被拷贝。

2. 无法处理 undefinedSymbol 类型

JSON.stringify() 会忽略对象中的 undefinedSymbol 类型的属性。这就像在“蓝图”里把这些类型的属性当成不存在一样。

代码示例

javascript">const obj = {name: '孙七',age: undefined,[Symbol('key')]: 'value'
};const clonedObj = JSON.parse(JSON.stringify(obj));console.log(clonedObj); 
// 输出: { name: '孙七' }

age 属性和 Symbol 类型的属性都没有被拷贝。

3. 无法处理循环引用

循环引用就是对象的属性指向了对象本身或者形成了一个循环的引用关系。JSON.stringify() 遇到循环引用会报错,就像“蓝图”画到一半发现陷入了一个死循环,不知道该怎么画下去了。

代码示例

javascript">const obj = {};
obj.self = obj;try {const clonedObj = JSON.parse(JSON.stringify(obj));
} catch (error) {console.log(error); // 输出: TypeError: Converting circular structure to JSON
}

这里 objself 属性指向了 obj 本身,JSON.stringify() 处理时就会报错。


http://www.ppmy.cn/embedded/164969.html

相关文章

PHP MySQL 读取数据

PHP MySQL 读取数据 引言 在Web开发中&#xff0c;PHP和MySQL是两个常用的技术。PHP是一种服务器端脚本语言&#xff0c;而MySQL是一个关系型数据库管理系统。两者结合&#xff0c;可以构建强大的动态网站。本文将详细介绍如何使用PHP和MySQL进行数据的读取操作。 PHP与MySQ…

git@ccc.coding.net: Permission denied (publickey).

在使用composer update时发生了以下错误 gitccc.coding.net: Permission denied (publickey). 这个错误通常是由于git没有通过ssh密钥认证&#xff0c;无法连接到远程仓库。 需要对ssh做一下配置。 检查本地是否有ssh密钥存在 ls -al ~/.ssh如果有id_rsa相关的内容&#xff…

【Python爬虫(46)】解锁分布式爬虫:实时数据处理的奥秘

【Python爬虫】专栏简介&#xff1a;本专栏是 Python 爬虫领域的集大成之作&#xff0c;共 100 章节。从 Python 基础语法、爬虫入门知识讲起&#xff0c;深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑&#xff0c;覆盖网页、图片、音频等各类数据爬取&#xff…

Docker 的安全配置与优化(一)

引言 在当今快速发展的云计算和 DevOps 时代&#xff0c;Docker 作为容器化技术的佼佼者&#xff0c;已经成为现代开发和运维的基石。它以其独特的优势&#xff0c;如环境隔离、快速部署、资源高效利用等&#xff0c;极大地改变了软件交付和运行的方式。在微服务架构中&#x…

Deepin(Linux)设置开机自动启动 MySQL

要在系统启动时自动启动 MySQL&#xff0c;可以通过配置 systemd 来实现。由于已经完成了 MySQL 的安装并且能够启动 MySQL 服务&#xff0c;接下来我们将创建一个 systemd 服务单元文件&#xff0c;让 MySQL 在系统启动时自动启动。 1. 创建 systemd 服务文件 首先&#xff…

设备唯一ID获取,支持安卓/iOS/鸿蒙Next(uni-device-id)UTS插件

设备唯一ID获取 支持安卓/iOS/鸿蒙(uni-device-id)UTS插件 介绍 获取设备唯一ID、设备唯一标识&#xff0c;支持安卓&#xff08;AndroidId/OAID/IMEI/MEID/MacAddress/Serial/UUID/设备基础信息&#xff09;,iOS&#xff08;Identifier/UUID&#xff09;&#xff0c;鸿蒙&am…

C++:pthread的使用

pthread 简介 pthread 是 POSIX 线程&#xff08;POSIX Threads&#xff09;的简称&#xff0c;它是 POSIX 标准中定义的线程接口规范。pthread 库提供了一系列函数&#xff0c;用于创建、销毁、同步和管理线程。在类 Unix 系统&#xff08;如 Linux、macOS&#xff09;中&…

想学python进来看看把

目录 什么是python 我将列举python与其他几种编程语言的对比 Python vs Java Python vs JavaScript Python vs C​编辑 我将列举代码示例帮大家来理解 python c/c java 写一个python程序 你一定要知道什么是BUG呦 遇到bug怎么办 1. 保持冷静 2. 重现 Bug 3. 阅…