深浅拷贝的克隆

浅拷贝:复制引用,一个变化另外一个也会变化

深拷贝:复制的不是引用

 

clone()  只是克隆当前节点
clone(true)  只是克隆当前节点和子节点

### JavaScript深拷贝浅拷贝的概念 在 JavaScript 编程中,深拷贝浅拷贝主要涉及引用数据类型的复制行为。对于基本数据类型(如字符串、数字),其值会被直接复制;而对于复杂数据类型(如对象、数组),则需要区分是浅拷贝还是深拷贝。 #### 浅拷贝 (Shallow Copy) 浅拷贝是指创建一个新的对象或数组,并将其原始对象的第一层属性值复制过去。如果这些属性本身也是引用类型,则只会复制它们的引用地址而非实际内容。因此,在修改新对象中的某些嵌套属性时,可能会间接改变原对象的内容[^1]。 #### 深拷贝 (Deep Copy) 相比之下,深拷贝不仅复制顶层属性,还会递归地复制每一层嵌套结构下的所有属性及其具体值。这意味着即使是最深层级上的引用类型也会被完全独立出来,从而确保源对象不会受到目标对象任何改动的影响[^3]。 --- ### 实现方式 以下是几种常见的实现方法: #### 方法一:使用 JSON 序列化/反序列化 这是最简单的一种实现深拷贝的方式之一,适用于不包含函数或者特殊类型(比如 Date 对象)的情况。 ```javascript function deepCopy(obj) { return JSON.parse(JSON.stringify(obj)); } ``` 这种方法虽然方便快捷,但它存在局限性——无法正确处理循环引用以及一些特殊的内置对象类型,例如 `Map` 和 `Set` 等[^2]。 #### 方法二:手动递归克隆 通过编写自定义逻辑来逐层遍历并复制每一个字段直到达到最终节点为止。这种方式可以更好地控制整个过程并且支持更多种类的数据形式包括但不限于日期实例、正则表达式等等。 ```javascript function isObject(val) { return val !== null && typeof val === 'object'; } function customDeepClone(source, hash = new WeakMap()) { if (!isObject(source)) return source; // 防止循环引用 if (hash.has(source)) return hash.get(source); const result = Array.isArray(source) ? [] : {}; hash.set(source, result); for (const key in source) { if (source.hasOwnProperty(key)) { result[key] = customDeepClone(source[key], hash); } } return result; } ``` #### 方法三:利用第三方库 lodash 的 _.cloneDeep() Lodash 是一个非常流行的工具类库,其中提供了专门用于执行深度副本操作的功能即_.cloneDeep() ,它能够很好地解决上述提到的各种问题同时保持较高的性能表现。 ```javascript // 安装lodash npm install --save lodash const _ = require('lodash'); let obj = { a: 1, b: { c: 2 } }; let clonedObj = _.cloneDeep(obj); clonedObj.b.c = 99; console.log(clonedObj); //{a: 1, b: {c: 99}} console.log(obj); //{a: 1, b: {c: 2}} ``` --- ### 总结 综上所述,无论是采用哪种技术手段来进行深拷贝亦或是浅拷贝都需要根据实际情况作出合理的选择。当面对简单的场景时可以选择较为简便高效的解决方案如JSON stringify / parse组合而成的技术路线图;而遇到更加复杂的业务需求则建议考虑引入成熟的开源框架辅助完成任务以降低开发成本提高代码质量.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值