深度克隆与浅度克隆

本文介绍了JavaScript中的深度克隆和浅度克隆概念,通过实例代码展示了浅度克隆的实现,并分析了其存在的问题——对于引用类型数据的处理。接着,解释了深度克隆的原理,即通过递归处理引用类型来确保新对象独立于原对象。最后,给出了深度克隆的示例代码。

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

上星期再次研究了一下以前不太清楚的深度克隆,经过连续的写了3次之后终于清晰了一点,记录一下思路。

show me my code

var user={
    name:'姓名',
    gender:'性别',
    Tags:['标签1','标签2']
}

顾名思义,浅度克隆就是指复制啦~

Object.prototype.clone=function(){
    var newObj={};
    for(var key in this){
        if(this.hasOwnProperty(key)){
            newObj[key]=this[key];
        }
    }
    return newObj;
};
var jack=user.clone();
jack.name='jack';
jack.gender='男';
jack.Tags.push('男神');

结果如下:
浅度克隆结果

ok,我们这里就完成了浅度克隆了,由于我是对整个Object的原型写函数来继承的,所以我在循环内判断了一下属性是否为自身的自有属性,是的话才能复制,解决了会继承复制clone函数的小问题,如果不判断,在结果中会出现clone函数,因为我们这里是对所有对象原型写的继承函数。

那么浅度克隆的问题在哪了,接下来大家就会看到了
假如这时候又多了个妹子

var mary=user.clone();
mary.name='mary';
mary.gender='女';
mary.Tags.push('女神');

结果如下:
浅度克隆问题

问题显而易见,图中对象顺序依次为mary、jack、原对象,很明显我们想要的效果其实是jack在Tags中是['标签1','标签2','男神'],mary的Tags是['标签1','标签2','女神'],而现状是全部的Tags都变为了['标签1','标签2','男神','女神'],原对象也是,而造成这个问题的原因就是数组是引用类型的= =…这个是基础知识,我想大家都是知道的,所以简单的赋值只是将数组地址赋给了新对象而已,真正引用和更改的仍然是原对象中的数组;

那么解决方法已经很明显了,判断一下是否为引用类型,将引用类型内的元素都赋值就好,利用递归函数就可以巧妙的解决,这就是深度克隆的原理了,下面上深度克隆demo:

Object.prototype.deepClone=function(){

    var newObj = this.constructor == Array?[]:{};//判断克隆对象构造函数为数组

    for(var key in this){
        if(this.hasOwnProperty(key)){
            if(typeof this[key] == "object"){
                newObj[key] = this[key].deepClone();
            }
            else{
                newObj[key] = this[key];
            }
        }
    }  
    //如果是构造函数的情况请加上,不然父深度克隆后的父链并不会指向原构造函数而是Object
    //  newObj.__proto__ = this.__proto__;
    return newObj;
};

var kalista = user.deepClone();
kalista.name='卡利斯塔';
kalista.gender='女';
kalista.Tags.push('LOL');
console.log(kalista);

var jugg=user.deepClone();
jugg.name='剑圣';
jugg.gender='男';
jugg.Tags.push('DOTA');
console.log(jugg);

结果如下:
深度克隆

完成~我写的函数还是比较简单的,我就不说明了,原理在上面也说过了,实现过程就跟原理所说的一样,需要注意的只是数组的typeof为object与记得递归后的赋值而已,over~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值