1. 程式人生 > 實用技巧 >什麼是深拷貝?什麼是淺拷貝?如何實現深拷貝?

什麼是深拷貝?什麼是淺拷貝?如何實現深拷貝?

深拷貝和淺拷貝是針對引用型別的

淺拷貝:

簡單來說就是一個物件B複製另一個物件A,當改變B物件的值是A物件的值也隨之改變

舉個例子

var  obj1={a:1,b:5,c:3};
var  obj2=obj1;
obj2.b=2;
console.log(obj1.b);  //2
console.log(obj2.b);  //2

可以看到兩個物件的值都被修改了。

淺拷貝:就是拷貝物件的引用,而不深層次的拷貝物件的,多個物件指向堆記憶體中的同一物件,,任何一個修改都會是使得所有物件的值被修改,因為它們公用一條資料。

深拷貝:

簡單來說就是一個物件B複製另一個物件A,當改變B物件的值是A物件的值不會改變

舉個例子:

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

以上例子說明兩個變數使用的是獨立的資料。對於基本資料型別來說不存在深拷貝、淺拷貝。直接賦值就是深拷貝。

深拷貝:深拷貝不會拷貝引用型別的引用,拷貝的是引用型別的值,形成一個新的引用型別。

如何實現深拷貝:

JSON.Stringify(JSON.pare()) 不支援多層引用巢狀,不支援函式Map、Sep等型別的資料

var  obj1={a:1,b:5,c:3};
var  obj2=JSON.Stringify(JSON.parse(obj1));
obj2.b
=2; console.log(obj1.b); //5 console.log(obj2.b); //2

展開運算子 ...

var  obj1={a:1,b:5,c:3};
var  obj2=(...obj1)
obj2.b=2;
console.log(obj1.b);  //5
console.log(obj2.b);  //2

Object.asssign(target,sourse)

var  obj1={a:1,b:5,c:3};
var  obj2=Object.assign({},obj1)
obj2.b=2;
console.log(obj1.b);  //5
console.log(obj2.b);  //
2

深拷貝函式,遞迴

            // target 要拷貝的物件
            function deepClone(target){
                //定義一個拷貝物件
                let result;
                // 判斷拷貝目標是不是Object物件
                if(typeof target==='object'){
                    // 判斷是否是陣列型別
                    if(Array.isArray(target)){
                        // 定義為陣列
                        result=[];
                        for(let i in target){
                            result.push(deepClone(target[i]));
                        }
                    }else if(target===null){
                        // 直接賦值
                        result=null;
                    }else if(target.constructor===RegExp){
                        // 直接賦值
                        result=target;
                        // 不是特殊的物件
                    }else{
                        result={};
                        for(let i in target){
                            // 遞迴
                            result[i]=deepClone(target[i]);
                        }
                    }
                    // 基本資料型別  直接賦值
                }else{
                    result=target;
                }
                return result;
            }

var obj1={
a:{z:1,c:null},
b:[1,2,3,5],
c:function(){console.log(this.a)}
}
var obj2=deepClone(obj1);
console.log(obj2);
obj2.b[0]=2;
obj2.a[0]=2;
console.log(obj1.a)
console.log(obj2.a)
console.log(obj1.b)
console.log(obj2.b)
console.log(obj2.c())