在JavaScript中,拷贝对象是一个常见的操作,根据拷贝的深度,我们可以将拷贝分为浅拷贝和深拷贝。
浅拷贝:创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝,如果属性是基本类型,拷贝的就是基本类型的值;但如果属性是引用类型,拷贝的就是内存地址(即引用)的一份拷贝,如果其中一个对象改变了引用类型的属性,另一个对象的该属性也会受到影响。
深拷贝:创建一个新对象,和原始的对象不共享内存,修改新对象不会影响原始对象,反之亦然。
接下来,我会详细解释如何在JavaScript中进行浅拷贝和深拷贝。
浅拷贝
1. Object.assign() 方法
Object.assign()
方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,它将返回目标对象。
let obj1 = { a: 1, b: 2, c: { d: 3 } }; let obj2 = Object.assign({}, obj1); obj2.c.d = 4; console.log(obj1.c.d); // 输出 4,因为 obj2.c 和 obj1.c 指向同一个对象
2. 扩展运算符
扩展运算符(…)允许一个表达式在某处展开,当用于对象时,它会生成由对象的所有可枚举键值对组成的数组。
let obj1 = { a: 1, b: 2, c: { d: 3 } }; let obj2 = { ...obj1 }; obj2.c.d = 4; console.log(obj1.c.d); // 输出 4,因为 obj2.c 和 obj1.c 指向同一个对象
深拷贝
1. JSON.parse() 和 JSON.stringify()
这是最简单的深拷贝实现方式,但它有局限性,例如不能处理函数和循环引用。
let obj1 = { a: 1, b: 2, c: { d: 3 } }; let obj2 = JSON.parse(JSON.stringify(obj1)); obj2.c.d = 4; console.log(obj1.c.d); // 输出 3,因为 obj2.c 是 obj1.c 的一个全新副本
2. 递归方法
通过递归遍历对象的所有属性,如果属性值是对象,则递归调用深拷贝函数。
function deepClone(obj, hash = new WeakMap()) { if (obj instanceof RegExp) return new RegExp(obj); if (obj instanceof Date) return new Date(obj); if (obj === null || typeof obj !== 'object') return obj; if (hash.has(obj)) return hash.get(obj); const result = Array.isArray(obj) ? [] : {}; hash.set(obj, result); for (let key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { result[key] = deepClone(obj[key], hash); } } return result; } let obj1 = { a: 1, b: 2, c: { d: 3 } }; let obj2 = deepClone(obj1); obj2.c.d = 4; console.log(obj1.c.d); // 输出 3,因为 obj2.c 是 obj1.c 的一个全新副本
3. Lodash 库的 _.cloneDeep() 方法
Lodash 是一个提供了一致性、自定义性、性能和实用性的工具库,它的 _.cloneDeep()
方法可以用于创建对象的深拷贝。
const _ = require('lodash'); let obj1 = { a: 1, b: 2, c: { d: 3 } }; let obj2 = _.cloneDeep(obj1); obj2.c.d = 4; console.log(obj1.c.d); // 输出 3,因为 obj2.c 是 obj1.c 的一个全新副本
在进行深拷贝时,选择哪种方法取决于具体需求和场景,简单的数据结构可以使用 JSON.parse()
和 JSON.stringify()
,而复杂的数据结构可能需要使用递归方法或第三方库如 Lodash。
原创文章,作者:酷盾叔,如若转载,请注明出处:https://www.kdun.com/ask/309182.html
本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。
发表回复