JS的浅拷贝和深拷贝的剖析以及部分实现方法

一、前言

JS的数据类型分为:基本数据类型和复杂数据类型。这两种不同的数据类型的数据的存放方式是有区别的,所以在拷贝赋值的时候就产生了深拷贝和浅拷贝的问题。

二、数据类型和存放位置

2.1、基本数据类型及其存放位置

JS的基本数据类型一般有5种:number(数字)、string(字符串)、boolean(布尔类型)、null(null型)、undefined(underfind型)。
存放位置:存储在里面,取用赋值的时候是值传递。

2.2、复杂数据类型及其存放位置

JS的复杂数据类型指引用数据类型,就是Object。像array,Object两种类型就属于复杂数据类型。
存放位置:它的指针(可以想象成路牌)一般存在中,(可以想象成目的地)存在中(我们通过路牌找到目的地,这里则是通过指针找到我们所需要的值)。

三、一窥“浅拷贝和深拷贝”真容

3.1、区分深拷贝与浅拷贝

通过表象区分深拷贝与浅拷贝,假设变量B复制了变量A,当修改变量A时,看变量B是否会发生变化,如果变量B也跟着变了,说明这是浅拷贝。如果变量B没变,那就是深拷贝。
代码说明:
浅拷贝(直接赋值):
简单数据类型:

var a = 7;
b = a;    // 栈内存会开辟一个新的内存空间,此时b和a都是相互独立的
b = 2;
console.log('a=', a);    // a=7

复杂数据类型:

let a=[0,1,2,3,4],
    b=a;
console.log(a===b);     // true
a[0]=1;							 
console.log(a,b);			// [1,1,2,3,4]     [1,1,2,3,4]

如果是基本数据类型,名字和值都会储存在栈内存中。但是复杂数据类型就会一改全改,因为它真正的数据是存在堆内存中的,并没有被复制成两个。
图解浅拷贝过程
复杂数据类型在栈和堆中存储状态:
在这里插入图片描述
复杂数据类型的浅拷贝结果:
在这里插入图片描述
复杂数据类型浅拷贝后的修改结果:
在这里插入图片描述
深拷贝:

由上图可知,在对复杂数据类型实现深拷贝的时候,不仅要拷贝栈内存中,还需要拷贝堆内存中的值。一般可以采用两种方式:
递归拷贝所有层级属性:

function deepClone(obj){
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                //判断ojb子元素是否为对象,如果是,递归复制
                if(obj[key]&&typeof obj[key] ==="object"){
                    objClone[key] = deepClone(obj[key]);
                }else{
                    //如果不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}    
let a=[1,2,3,4],
    b=deepClone(a);
a[0]=2;
console.log(a,b);

通过JSON对象来实现深拷贝:

function deepClone2(obj) {
  var _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
  return objClone;
}

**注意!**但是这种方法有一个缺点,无法实现对对象中方法的深拷贝,会显示为undefined。
图解深拷贝
在这里插入图片描述

3.2、一些说明

在实际应用中,浅拷贝和深拷贝是相对的,并不是绝对的。具体实现浅拷贝或者深拷贝要根据数据的结构采用具体的方法。举个栗子,for…in循环拷贝对象(数据),对于一层结构的对象一次循环拷贝就实现了深拷贝,但是如果这个对象数据是多层嵌套的数据格式,这次操作人就是浅拷贝。
参考链接:
js浅拷贝与深拷贝的区别和实现方式
JS的数据深拷贝和浅拷贝
欢迎大家一起讨论、学习。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值