js浅拷贝和深拷贝

本文详细介绍了JavaScript中的浅拷贝和深拷贝概念,包括它们的特点和区别。浅拷贝只复制一层对象,而深拷贝则递归复制所有层级。文章通过示例展示了如何使用Object.assign进行浅拷贝,并提供了一个自定义函数实现深拷贝。此外,还讨论了两种拷贝方式在性能和内存消耗上的差异。
摘要由CSDN通过智能技术生成

什么是浅拷贝?

浅拷贝只是拷贝一层, 更深层次对象级别的只拷贝引用(地址)。

浅拷贝的特点

(1) 对于基本数据类型的成员对象,因为基础数据类型是值传递的,所以是直接将属性值赋值给新的对象。基础类型的拷贝,其中一个对象修改该值,不会影响另外一个。

(2) 对于引用类型,比如数组或者类对象,因为引用类型是引用传递,所以浅拷贝只是把内存地址赋值给了成员变量,它们指向了同一内存空间。改变其中一个,会对另外一个也产生影响。

例如:

var obj = {
    id:1,
    name:'andy',
    mes:{
        age:18
    }
};

var o ={};

for(var k in obj){
    //k是属性名 obj[k]是属性值
    o[k] = obj[k];
}

console.log(o);

o.mes.age = 20;
console.log(obj);

打印结果:
在这里插入图片描述
为什么第一个输出的不是18,百度得出结论:因为console.log打印的是当前的值,展开后是最新修改后的值。

可以发现,把 obj 的mes属性赋值给 o 的时候赋值的是mes的地址,修改obj或o其中一个的mes,另一个的mes也会发生变化。

示意图:
在这里插入图片描述
es6新增的浅拷贝语法糖:Object.assign(o,obj); 等价于上面的for循环内容。

什么是深拷贝?

深拷贝拷贝多层,每一级别的数据都会拷贝。

深拷贝的特点

(1) 对于基本数据类型的成员对象,因为基础数据类型是值传递的,所以是直接将属性值赋值给新的对象。基础类型的拷贝,其中一个对象修改该值,不会影响另外一个(和浅拷贝一样)。

(2) 对于引用类型,比如数组或者类对象,深拷贝会新建一个对象空间,然后拷贝里面的内容,所以它们指向了不同的内存空间。改变其中一个,不会对另外一个也产生影响。

(3) 对于有多层对象的,每个对象都需要实现 Cloneable 并重写 clone() 方法,进而实现了对象的串行层层拷贝。

(4) 深拷贝相比于浅拷贝速度较慢并且花销较大。

如:

//深拷贝拷贝多层,每一级别的数据都会拷贝
var obj = {
    id:1,
    name:'andy',
    mes:{
        age:18
    },
    color:['pink','red'],
};

var o ={};

//封装函数

function deepCopy(newObj, oldObj){
    for(var k in oldObj){
        //判断我们的属性值属于哪种数据类型
        //1、获取属性值 oldObj[k]
        var item = oldObj[k];

        //2、判断这个值是否是数组
        if(item instanceof Array){
            newObj[k] = [];
            deepCopy(newObj[k], item);
        }else if(item instanceof Object){
            //3、判断这个值是否是对象

            newObj[k] = {};
             deepCopy(newObj[k], item);
        }else{
            //4、属于简单数据类型
            newObj[k] = item;
        }
    }
}
deepCopy(o,obj);
console.log(o);

示意图如下:

引用类型的值都是 Object 的实例。引用类型有:Object类型,Array类型,Date类型,RegExp类型(正则),function类型。还有基本包装类型,也是一种引用类型。ECMAScript还提供了 3个特殊的引用类型:Boolean、Number和String。
在这里插入图片描述
附:
引用类型的值都是 Object 的实例。引用类型有:Object类型,Array类型,Date类型,RegExp类型(正则),function类型。还有基本包装类型,也是一种引用类型。ECMAScript还提供了 3个特殊的引用类型:Boolean、Number和String。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值