js的深克隆与浅克隆

1.浅克隆

直接将存储在栈中的值赋值给对应变量,如果是基本数据类型,则直接赋值对应的值,如果是引用类型,则赋值的是地址。

function clone(Origin,Target){
        var Target = Target || {}
        for(var prop in Origin){
            Target[prop] = Origin[prop]
        }
        return Target;
    }
    var a = {
        name:'wcc',
        age:24,
        sex:{
            male:'true',
            female:'true'
        }
    }
    var b = clone(a);
    b.sex.male = 'false';
    b.age = 18;
    console.log(b.sex.male,a.sex.male,b.age,a.age)//false  false 18 24

可以发现使用浅克隆,如果修改的是引用类型,则原来的对象也会修改,若修改的基本数据类型则不会影响。

2.深克隆

把数据赋值给对应的变量,从而产生一个与源数据不相干的新数据(数据地址已变化)。深克隆是克隆对象各个层级的属性。

步骤:
1遍历对象
2.判断是不是原始值
3.判断是数组还是对象
4,.建立相应的数组或者对象
5.递归

 function deepClone(Origin, Target) {
            var Target = Target || {};
            for (var prop in Origin) {
                if (Origin.hasOwnProperty(prop)) {//如果返回false则说明为原型上的属性,不用拷贝
                    if (Origin[prop] !== 'null' && typeof (Origin[prop]) === 'object') {
                        if (Object.prototype.toString.call(Origin[prop]) === '[object Array]') {
                            Target[prop] = [];
                        } else {
                            Target[prop] = {};
                        }
                        //也可以简写为一行代码赋值
                        //Target[prop] = Object.prototype.toString.call(Origin[prop]) === '[object Array]' ? [] :{}
                        deepClone(Origin[prop], Target[prop]);//递归
                    } else {
                        Target[prop] = Origin[prop];
                    }
                }
            }
            return Target;
        }
        var a = {
            name: 'wcc',
            age: 24,
            sex: {
                male: 'true',
                female: 'true'
            }
        }
        var b = {};
        deepClone(a, b)
        b.sex.male = 'false';
        b.age = 18;
        console.log(b.sex.male, a.sex.male, b.age, a.age)//false  true 18 24

如果obj里有RegExpError对象,还需做其他的处理,除此之外还有一种简单的方法

		var b = JSON.parse(JSON.stringify(a));

使用上述方法时需要注意几点:

1、如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象

2、如果obj里有RegExpError对象,则序列化的结果将只得到空对象;

3、如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;

4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null

5、JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor

6、如果对象中存在循环引用的情况也无法正确实现深拷贝;

 

若只是克隆数组,也可以使用数组的concat方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值