如何在JavaScript中实现包含嵌套结构的对象深克隆?
JavaScript 对象深克隆方案
针对包含嵌套对象、数组的对象,以下是几种可靠的深克隆实现方式:
1. JSON 序列化/反序列化(快速但有局限)
这是最简单的实现方式,利用JSON.stringify()将对象转为JSON字符串,再用JSON.parse()解析为新对象:
let originalObj = { name: "John", age: 30, address: { street: "123 Main St", city: "Anytown" }, hobbies: ["reading", "gaming"] }; let clonedObj = JSON.parse(JSON.stringify(originalObj));
适用场景:对象仅包含基本类型、普通对象、数组,无特殊类型(如函数、undefined、Symbol、循环引用)。
缺点:无法处理函数、undefined、Symbol属性,会直接丢失;循环引用的对象会报错;Date对象会被转为字符串而非保留原类型。
2. 自定义递归克隆函数(灵活可控)
如果需要处理更多类型或自定义克隆逻辑,可以手写递归函数,逐个遍历对象/数组的属性并递归克隆:
function deepClone(obj, cache = new WeakMap()) { // 处理基本类型、null和函数 if (obj === null || typeof obj !== 'object') { return obj; } // 处理循环引用,避免无限递归 if (cache.has(obj)) { return cache.get(obj); } // 处理数组 if (obj instanceof Array) { const cloneArr = []; cache.set(obj, cloneArr); obj.forEach(item => cloneArr.push(deepClone(item, cache))); return cloneArr; } // 处理普通对象 const cloneObj = {}; cache.set(obj, cloneObj); for (const key in obj) { if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key], cache); } } return cloneObj; } // 使用示例 let clonedObj = deepClone(originalObj);
扩展优化:如果需要支持Date、RegExp、Map、Set等类型,可以在函数中添加对应的类型判断和克隆逻辑。比如:
// 处理Date对象 if (obj instanceof Date) { return new Date(obj.getTime()); } // 处理RegExp对象 if (obj instanceof RegExp) { return new RegExp(obj.source, obj.flags); }
3. 原生 Structured Clone API(现代环境首选)
现代浏览器和Node.js(17+,低版本可通过polyfill支持)提供了structuredClone()方法,原生支持深克隆,能处理JSON方法无法处理的类型(如循环引用、Date、RegExp、Map、Set):
let clonedObj = structuredClone(originalObj);
优点:原生实现无需手写代码,支持大部分JS内置类型,处理循环引用安全可靠。
缺点:不支持函数、Symbol属性(会抛出错误),旧环境(如IE)不兼容。
验证克隆效果
无论使用哪种方法,修改克隆后的对象属性都不会影响原对象:
clonedObj.address.city = "New City"; clonedObj.hobbies.push("hiking"); console.log(originalObj.address.city); // 输出 "Anytown" console.log(originalObj.hobbies); // 输出 ["reading", "gaming"]
内容的提问来源于stack exchange,提问作者yuekandy
相关产品推荐
相关产品推荐

