js手写深拷贝

本文详细介绍了JavaScript中深拷贝和浅拷贝的概念,并通过实例解析了两者的区别。针对多层嵌套对象的深拷贝问题,提出了两种解决方案:一种简单但存在局限性的JSON转换方法,另一种是递归实现的深拷贝函数。同时,文章强调了JSON.parse(JSON.stringify(obj))方法在处理对象自身引用时的限制,以及如何通过递归实现对复杂对象的完全复制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JS手写深拷贝

深拷贝:假设我有一个对象A,我赋值给B,无论怎么改变B,A都不会发生任何的改变,即为深拷贝

浅拷贝:假设我有一个嵌套对象A,我赋值给B,改变一下B里面的嵌套对象,A会跟着改变,而改变一下第一层的属性A却不改变,即为浅拷贝。

网上有很多说数组的slice、concat方法对数组使用,或者对象使用Object.assign()和ES6的扩展运算符(…)可以实现深拷贝,这是不对的,以上的方法只能对一层的对象有用,多层嵌套的是不起作用的,什么是多层嵌套,下面是两层,obj对象属性name也是一个对象,还可以无限嵌套,以上的方法对下面的多层嵌套是没用的。

var obj = {
age: 13,
name: {
addr: ‘天边’
}
}

下面两种方法实现了深拷贝,不管你是一层还是多层对象。

第一种:脑残法
function deepClone(obj) {
    if(typeof obj != 'object') return obj;
    return JSON.parse(JSON.stringify(obj))
}

// 测试
var obj = {
    name: 123
}
var obj1 = obj;
obj1.name = 345;
console.log(obj.name); // 345 这里看到 我们把obj赋值给obj1 然后修改obj1的name值,obj的name值同样发生了改变
var obj2 = deepClone(obj);
obj2.name = 678
console.log(obj.name); //345 把obj赋值给obj2 然后修改obj2的name值 obj的值不发生改变

上面的脑残法简单粗暴,但是有一个缺陷:

function deepClone(obj) {
        if (typeof obj != 'object') return obj;
        return JSON.parse(JSON.stringify(obj))
    }
    // 测试
    var obj = {
        name: 123
    }
    obj.test = obj
    var obj1 = obj;
    var obj2 = deepClone(obj);

如果有对自身的引用,obj有一个属性名叫test,他的值就是obj本身,这个时候就报错了,报错如下,说明使用的JSON.parse(JSON.stringify(obj))的前提是对象不能有对自身的引用
在这里插入图片描述

第二种:递归法
function deepClone(obj) {
    if (typeof obj != 'object') return obj;
    var temp = Array.isArray(obj) ? [] : {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (obj[key] && typeof obj[key] == 'object') { // 如果obj[key]还是对象则执行递归
                temp[key] = deepClone(obj[key]); // 递归
            } else {
                temp[key] = obj[key];
            }
        }
    }
    return temp;
}

var obj = {
    age: 13,
    name: {
        addr: '天边'
    }
}

var obj2 = deepClone(obj);
obj2.age = 14
obj2.name.addr = '地心'
console.log(obj.age); //13
console.log(obj.name.addr); //天边
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值