JavaScript深拷贝与浅拷贝的区别,实现深拷贝的几种方法

时间:2022-10-10 19:57:18

如何区分深拷贝与浅拷贝,针对js数据引用类型,以数组a,数组b为例:

假设数组b是复制数组a后拿到的,

浅拷贝:a,b相互影响(修改a的值影响b的值,同理b影响a)

深拷贝:a,b各自独立(互不影响)。

原理涉及到栈堆基本数据类型引用数据类型,自行查阅。

1.借用JSON对象的parse和stringify

var a = [1, 2, 3];
//浅拷贝
var b = a;
b.push(4);
console.log(a); //[1,2,3,4]
console.log(b); //[1,2,3,4]

//深拷贝
var c =JSON.parse(JSON.stringify(obj));
c.push(4);
console.log(a); //[1,2,3]
console.log(c); //[1,2,3,4]

2.借用jquery的extend方法。

$.extend( [deep ], target, object1 [, objectN ] )

deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝

target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。

object1  objectN可选。 Object类型 第一个以及第N个被合并的对象。

var a=[1,2,3];
//深拷贝
var b=$.extend(true,[],a);
a.push(4);
console.log(a);//[1,2,3,4]
console.log(b);//[1,2,3]

3.递归递归去复制所有层级属性。

这么我们封装一个深拷贝的函数(PS:只是一个基本实现的展示,并非最佳实践);

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);