如何在JavaScript中使用递归结合Object.create实现对象深拷贝
深拷贝函数实现方案
实现思路
- 先判断传入值的类型,基础类型和null直接返回原值即可
- 引入
WeakMap做缓存,解决对象循环引用导致的递归死循环问题 - 区分数组和普通对象两种引用类型:数组直接创建新数组实例;普通对象用
Object.create继承原对象的原型链,保证原型属性不丢失 - 遍历原对象的所有自有属性,递归拷贝每一个属性值后赋值给新对象
function cloneDeep(obj, cache = new WeakMap()) { // 基础类型、null直接返回 if (obj === null || typeof obj !== 'object') { return obj } // 已经拷贝过的对象直接返回缓存结果,处理循环引用 if (cache.has(obj)) { return cache.get(obj) } let cloneTarget if (Array.isArray(obj)) { cloneTarget = [] } else { // 继承原对象的原型链,符合Object.create的使用要求 cloneTarget = Object.create(Object.getPrototypeOf(obj)) } // 存入缓存 cache.set(obj, cloneTarget) // 遍历自有属性递归拷贝 for (const key in obj) { if (obj.hasOwnProperty(key)) { cloneTarget[key] = cloneDeep(obj[key], cache) } } return cloneTarget }
效果验证
用你提供的person对象测试,修改拷贝后对象的深层属性不会影响原对象:
const person = { name: "Vikram", age: 21, place: { country: "India", state: "Karnataka", }, marks: [1, 2, 3, 4], parents: { father: "Ramesh", mother: "Suma", }, }; const clonedPerson = cloneDeep(person) clonedPerson.place.state = "Kerala" console.log(person.place.state) // 输出 Karnataka,原对象不受影响 console.log(clonedPerson.place.state) // 输出 Kerala
内容的提问来源于stack exchange,提问作者Nithyashree B L
相关产品推荐
相关产品推荐

