对象拷贝

平时编程时,少不了要进行赋值操作,赋值意味着着要进行拷贝,但是由于js的数据类型不同,导致拷贝方式不同,结果也不就同。

具体的数据类型包括:

基本类型(Number,String,Boolean,Null,Undefined ,Symbol ):存放于栈内存;

引用类型(Object):存放与堆内存。

基本类型的数据进行拷贝时,只需要将具体的值进行复制,拷贝到对应新变量中去即可;但是,对于引用类型的数据,复制意味着只是将引用类型的数据地址复制被复制给新的变量,最终的结果就是两个变量指向同一个在堆内存中的对象,改变一个,另外的一个对象也会发生变化。因此,对于复制拷贝有了两种方式:浅拷贝,深拷贝。

 

浅拷贝

将对象的各个属性进行依次复制,不会递归复制。当对于目标对象第一层为基本数据类型的数据,就是直接赋值,即「传值」;而对于目标对象第一层为引用数据类型的数据,就是直接赋存于栈内存中的堆内存地址,即「传址」,并没有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会改变。

//浅拷贝==》复制对象所有属性都不是引用类型
//遍历并复制,返回新对象
//浅拷贝会复制所有的引用对象的指针,而不是具体的值
function shallowCoyp(obj){
    var coyp={};
    for(key in obj){
        if(obj.hasOwnProperty(key)){//只复制本身拥有的属性
            coyp[key]=obj[key];
        }
    }
    return coyp;
}

深拷贝

对浅拷贝的进一步改进。

1、粗暴方式:JSON.parse(JSON.stringify(obj))

缺点:

  • undefined、任意的函数、正则表达式类型以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时);
  •  它会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object;
  •  如果对象中存在循环引用的情况无法正确处理

2、其他

//深拷贝==》复制拥有所有的属性和方法的新对象
//粗暴方式:JSON.parse(JSON.stringify(obj))
//缺点:
//1 undefined、任意的函数、正则表达式类型以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时);
//2 它会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object;
//3 如果对象中存在循环引用的情况无法正确处理
function deepCopy1(obj){
    if(typeof obj!='object'){
        return obj;
    }else{
        var newobj={};
        for(var oo in obj){
            newobj[oo]=deepCopy1(obj[oo]);
        }
        return newobj;
    }
}
// ||||对象引用循环???
//解决循环引用
var hasarr = [];
function deepCopy2(obj) {
    let copy = {};
    hasarr.push(obj);
    for (let i in obj) {
        if (typeof obj[i] === 'object') {
            let index = hasarr.indexOf(obj[i]);
            if (index > -1) {
                // 引用了相同对象,那么无论是循环引用还是重复引用,我们返回引用就可以了
                copy[i] = hasarr[index];
            } else {
                copy[i] = deepCopy2(obj[i]);
            }
        } else {
            copy[i] = obj[i];
        }
    }
    return copy;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值