Js<浅拷贝和深拷贝>

2020-08-19  本文已影响0人  誰在花里胡哨
遇到问题:

首先来看这段代码

    let a = 1;
    let b = a;
    a = 2;
    console.log(a,b);
image.png

然后再看这段代码
~~按道理来说b应该不会改变的,然而事实它却改变了~~

    let a = [1, 2, 3, 4, 5];
    let b = a;
    a[0] = 2;
    console.log(a, b);
image.png
知识点:

对比上面两个例子,就牵扯到了以下几点:

栈堆:具体可以参考 此篇文章,其中有针对 基本数据复杂(引用)数据 的解释

基本数据类型:number,string,boolean,null,undefined,symbol以及未来ES10新增的BigInt(任意精度整数)七类

引用数据类型:无序对象{a:1},数组[1,2,3],以及函数等

深拷贝与浅拷贝:简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力

解决问题:

方法1:
点击参考 es6中扩展运算符(...)

下面只是针对遍历一层的拷贝来解决的问题。
实际上, 展开语法和 Object.assign() 行为一致, 执行的都是浅拷贝(只遍历一层)

//数组
let b = [...a];

//对象
let b = {...a};

方法2:
采用递归递归的方式,去复制所有层级属性
这里封装一个深拷贝的函数(只是一个基本实现的展示,并非最佳实践)

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];
let b=deepClone(a);
a[0]=2;
console.log(a,b);
image.png

方法3:
除了递归,我们还可以借用JSON对象的parse和stringify

    function deepClone(obj) {
        let _obj = JSON.stringify(obj);
        let objClone = JSON.parse(_obj);
        return objClone
    }
    let a = [1, 2, 3, 4];
    let b = deepClone(a);
    a[0] = 2;
    console.log(a, b);
image.png
以上内容都是参考了 深拷贝与浅拷贝的区别,实现深拷贝的几种方法 文章受益匪浅,想了解更多的,大家可以去看原文章~~
上一篇下一篇

猜你喜欢

热点阅读