什么是 JavaScript 深度拷貝

前言:

面試的時候碰到了這么個問題,在這里總結一下。
什么是 Javacript 深度拷貝,既然有深度拷貝,那有沒有淺度拷貝呢?答案是有的。

舉個簡單的例子解釋一下:

淺度拷貝:就好比我們從俄羅斯買了20架蘇27戰斗機,飛機人家是給你了,但是技術并沒轉讓,飛機壞了還得求人家來給你修。

深度拷貝:就好比我們從俄羅斯買了20架蘇27戰斗機,并且轉讓了全部技術,這樣,我們就能自己生產了,技術全挖過來了,俄羅斯管不著了。

第一節 對象的拷貝

1、淺度拷貝
var a = {
    name:'aa',
    age:'20'
}
b = a;
b; //結果如下
/*
b = {
    name:'aa',
    age:'20'
}
*/

問:我們將對象 a 作一下修改,b 是否會跟著變?

var a = {
    name:'aa',
    age:'20'
}
b = a;
// 那么
b = {
    name:'aa',
    age:'20'
}

a.name = 'cc';
b;
/* b = { name:'cc',age:'20' } */

對象 b 是會跟著對象 a 的變動而變化的,這個我想大家應該都明白。

2、深度拷貝

就是 a 對象的操作不會影響到 b 對象(當然,反過來亦如此)

var a = {
    name:'yy',
    age:26
};
var b = new Object();
// 注意重點來了
b.name=a.name;
b.age=a.age;

a.name='xx';
console.log(b);
//Object { name="yy", age=26}
console.log(a);
//Object { name="xx", age=26}

哎呦,還真是,對象 a 變了而對象 b 沒發生變化。

總結一下,其實是這樣的。
1.淺度拷貝:基本類型為值傳遞,對象仍為引用傳遞。
2.深度拷貝:所有元素或屬性完全克隆,對于原引用類型完全獨立。

上面這種寫法,對象屬性很少的情況下,是可以使用的,但是多了,就不行了。所以我們還是要寫個函數,將要拷貝的對象的屬性遍歷一遍,賦值給一個新對象。如下,

function deepCopy(source) {
    var result = {};
    for(var key in source) {
        result[key] = typeof source[key] === 'object'? deepCoyp(source[key]): source[key];
    } 
    return result;    
}

var a = {
    name: '小明',
    age: 18
}
b = deepCopy(a);
/* b = { name: '小明',age:18 }*/

同理,說一下數組的淺度拷貝和深度拷貝

第二節 數組的拷貝

1、淺度拷貝
var arr = [1,2,3];
var arr2 = arr;
console.log(arr2); // [1,2,3]
arr[0] = "one";
console.log(arr1); // ["one", 2, 3]
console.log(arr2); // ["one", 2, 3]

與對象的淺度拷貝是一樣的。

2、深度拷貝

方法1:利用 slice 函數

slice() 方法可從已有的數組中返回選定的元素。

arrayObject.slice(start,end)  // start 必選 end 可選

說明:
1.請注意,該方法并不會修改數組,而是返回一個子數組。
2.如果 end 未被規定,那么 slice() 方法會選取從 start 到數組結尾的所有元素。

var arr = [1,2,3];
var arr2 = arr.slice(0); // 重點看這里
console.log(arr2); // [1, 2, 3]
arr = ["one","two","three"];
console.log(arr); // ["one","two","three"]
console.log(arr2); // [1, 2, 3]

方法2:利用 concat 函數

concat() 方法用于連接兩個或者多個數組。

arrayObject.concat(arrayX,arrayX,......,arrayX)  

說明:
該方法不會改變現有的數組,而僅僅會返回被連接數組的一個副本

var arr = [1,2,3];
var arr2 = arr.concat();  // 重點看這里,concat 一個空數組進去,那結果不變
console.log(arr2); // [1, 2, 3]
arr = ["one","two","three"];
console.log(arr); // ["one","two","three"]
console.log(arr2); // [1, 2, 3]

總結:

說點題外話,做前端也有一段時間了,以前,碰到問題就加個書簽或者建個 word 簡要的記一下。從今年開始認真的在有道云筆記上寫筆記,并且把合適的推送到自己的博客上。個人覺得建立博客的意義除了知識共享以及備忘,更重要的一點是迫使自己去思考和總結,既要寫出來,還要別人能看懂,花費的時間挺多,但是值得。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容