JavaScript中的深淺拷貝問題詳解

數據類型

  • 基礎數據類型: 數值, 布爾, 字符串等
  • 引用數據類型: 數組 / 對象 
    只有引用數據類型纔有拷貝的問題

淺拷貝

var arr = [1, 2, 3, 4];
var brr = arr;
arr.push(5);
console.log(brr); // 結果: [1, 2, 3, 4, 5]
// 思考: 爲什麼往arr數組末尾插入元素5, brr數組也跟着改變了呢?

arr 和 brr變量中裝載的是數組的內存地址&7x0099(編的地址), 改變數組內容都是在改變這個連續地址中的&7x0099內的值, 所以他倆都收到影響 

深拷貝

var arr = [1, 2, 3, 4];
var brr = new Array();
arr.map(item => {
    brr.push(item);
})
arr.push(5);
console.log(brr); // 結果: [1, 2, 3, 4]
// 思考: 爲什麼這次arr沒有影響brr呢?

brr的值, 保存了一個new Array()新開闢的地址空間, 所以brr和arr不在指向同一個數組了 

多層深拷貝

項目中數組/對象常用深克隆方式(可拷貝多層)

// 方式1:
function deepClone(obj){
    // 判斷參數是數組還是對象, 準備一個空的
    let objClone = Array.isArray(obj) ? [] : {};
    // 非空, 並且是對象  (array或者object的typeof都是object)
    if(obj && typeof obj === "object"){
        // 遍歷數組/對象
        for(key in obj){
        // 判斷是否是當前對象的屬性(防止複製原型鏈上的對象)
            if(obj.hasOwnProperty(key)){
            //判斷obj子元素是否爲對象,如果是,遞歸複製
                if(obj[key] && typeof obj[key] === "object"){
                    objClone[key] = deepClone(obj[key]);
                } else {
                    //如果不是,簡單複製
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}
// 方式2:
JSON.parse(JSON.stringify(obj));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章