JS中深克隆和浅复制详解

深克隆和浅复制的基本定义

浅复制(浅克隆):直接将存储在栈中的值赋值给对应变量,如果是基本数据类型,则直接赋值对应的值,如果是引用类型,则赋值的是地址
深复制(深克隆):就是把数据赋值给对应的变量,从而产生一个与源数据不相干的新数据(数据地址已变化)。深拷贝,是拷贝对象各个层级的属性。

demo1-基本数据类型的赋值(以String为例)

let a = "hello world";
let b = a;
alert( b ); // 'hello world'
a = "changed";
alert( b ); // 'hello world'

// 在这段代码中,把a赋值给b,当a的值发生变化时,并不影响b

demo2-引用数据类型的赋值(以Array为例)

let arr1 = [1, 2, 3, 4];
let arr2 = arr1;
console.log( arr2 );  // [10, 2, 3, 4]
arr1[0] = 10;
console.log( arr2 );  // [10, 2, 3, 4]

// 在这段代码中,把arr1赋值给arr2,当arr1的值改变时,arr2对应的值也会改变

对以上两个例子的分析

  1. 对于基本数据类型而言,把a的值赋值给b后,a的修改,不会影响到b。
  2. 对于引用数据类型而言,把arr1赋值给arr2后,arr1的修改,会影响到arr2对应的值
  3. 基本数据类型是直接存储在栈内存中的,而引用数据类型,则仅仅是把地址存储在栈内存中,真正的数据是存储在堆内存中的,赋值操作时,仅仅把地址进行了赋值。

实现深克隆的方式

方法一: 递归
function deepClone( obj ){
    let objClone = Array.isArray(obj) ? [] : {};
    if( obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                if(obj[key]&&typeof obj[key] ==="object"){
                    objClone[key] = deepClone(obj[key]);
                }else{
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}    
let a=[1,2,[2, 3],4],
    b=deepClone(a);
a[2][0]=10;
console.log(a,b);
方法二: JSON.stringify 和 JSON.parse
function deepClone(obj){
    let _obj = JSON.stringify(obj),
        objClone = JSON.parse(_obj);
    return objClone
}    
let a=[0,1,[2,3],4],
    b=deepClone(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);
方法三: jQuery中的 $.extend

$.extend( [deep ], target, object1 [, objectN ] )
deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。

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

你可能感兴趣的:(JS中深克隆和浅复制详解)