#过年不停更# 前端JavaScript深浅拷贝理解 原创

wx61e57c405ac83
发布于 2022-1-21 19:44
浏览
0收藏

春节不停更,此文正在参加「星光计划-春节更帖活动」
相信小伙伴们经常会听到前端面试中提到深浅拷贝的问题,这里给大家分享一下我的理解

在js中有基本数据类型和复杂数据类型

基本数据类型存储在栈中,而复杂数据类型存储在堆中通过指针指向地址相连接

#过年不停更# 前端JavaScript深浅拷贝理解-鸿蒙开发者社区

下面用代码来理解一下

var arr = [1,2,3];
var newArr = arr;
console.log(arr,newArr); // [ 1, 2, 3 ] [ 1, 2, 3 ]

如果我们给newArr末尾添加一个4 再打印一下会出现什么结果

var arr = [1,2,3];
var newArr = arr;
newArr.push(4)
console.log(arr,newArr);  //[ 1, 2, 3, 4 ] [ 1, 2, 3, 4 ]

你会发现明明只给newArr添加了数据为什么arr也跟着增加了数据,这是因为:我们在创建了arr这个数组的时候,产生了一个指针指向这个数组,同时我们吧arr的指针共享给了newArr,他们就存在一个相同的指针同时指向同一个数组,得出一个结论,复杂数据类型在赋值的时候是共享内存空间的。很好理解

同理基本数据类型是不会存在共享内存空间这种情况的

var a = 1;
var b = a;
b = 2;
console.log(a,b); //1,2

很容易得得出了一个结论,基本数据类型是独立的,而复杂数据类型是共享的

基本数据类型:一般是浅拷贝,数据相互独立,互不影响

复杂数据类型:一般不是独立,相互影响

深拷贝和浅拷贝的区别

b复制a,当a修改时,b如果变了,浅拷贝,b没变,深拷贝

深拷贝

我们用代码实现一下深拷贝:

递归的方法

//递归的方法实现深拷贝
let a = [1,2,3,4]; //{}
let b = deepClone(a);
a[0]=22
console.log(a,b);
function deepClone(obj) {
    let objClone = Array.isArray(obj)?[]:{} //判断是不是数组还是对象
    if(obj && typeof obj=="object"){ //保证obj存在且是一个对象
        for(key in obj){
            if(obj.hasOwnProperty(key)) { //如果obj中有key属性
                if(obj[key] && obj[key] ==="object") {//判断二维或者是多维数组
                    //递归调用
                    objClone[key]=deepClone(obj[key])
                }else{//一维数组
                    objClone[key] = obj[key]
                }
            }
        }
    }
    return objClone;
}

这样打印出的结果是:[ 22, 2, 3, 4 ] [ 1, 2, 3, 4 ],很明显a发生改变了而b没改变,这就实现了深拷贝 深拷贝的核心就是要拷贝没个层级 中的属性和内容

当然有同学投机取巧,用js的slice方法实现拷贝,但是如果只是一维数组,是符合条件的,但是如果是多维数组,在改变值的时候,会跟着改变,这样就不叫深拷拷贝了,比如以下代码

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

乍一看很符合条件嘛 a变b不变,但是如果a为多维数组

let a = [1,2,[3,5],4]
let b = a.slice()
a[0]=22
a[2][0]=33
console.log(a,b);//[ 22, 2, [ 33, 5 ], 4 ] [ 1, 2, [ 33, 5 ], 4 ]

显然就不符合多维数组的概念

用parse和stringfy也可以实现深拷贝

let a = [1,2,[3,4],5];
let b = deepClone(a)
a[0]=22;
a[2][0]=333
console.log(a,b); //[ 22, 2, [ 333, 4 ], 5 ] [ 1, 2, [ 3, 4 ], 5 ]
function deepClone(obj) {
    let _obj = JSON.stringify(obj)
    let objClone = JSON.parse(_obj)
    return objClone;
}

这种方法不仅代码少而且性能好,推荐大家使用。

浅拷贝

1.对复杂类型赋值本身就是浅拷贝

2.es6的语法实现

Object.assign({},{})

Array.form()这里就不多演示了 钱拷贝比较简单主要符合前面a变b也变就是浅拷贝,咱们重点还是深拷贝,因为在面试中深拷贝是绝对迈不过去的坎,大家写程序时紧咬住ab的变化,就是共享内存空间,实际上指向同一个内存地址。

那么关于深浅拷贝的就分享到这儿

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
标签
已于2022-1-21 19:46:07修改
收藏
回复
举报
回复
    相关推荐