天天看點

JavaScript 對象數組的深淺拷貝

作者:陸榮濤

深淺拷貝

●深淺拷貝指的是一種複制對象或者數組的行為

●也就是把一個對象或者數組中的資料完完整整的複制一份放到另一個數組或者對象中

●并且互相之間沒有聯系

●說道深淺拷貝這個我們不考慮基本資料類型

●因為基本資料類型沒有引用位址一說

●說到複制這個事兒 有三個級别

○指派

○淺拷貝

○深拷貝

指派

●就是把一個變量存儲的内容複制一份給另一個變量

●基本資料類型指派以後兩個變量之間沒有關系

●修改任何一個的值都不會影響另一個

●複雜資料類型指派以後,兩個變量操作一個空間

●修改一個的值另一個也會跟着改變

// 指派
// 基本資料類型
let num = 100
let num1 = num
console.log(num, num1);
num1 = 200
console.log(num, num1);
// 複雜資料類型
let o1 = { name: 'Jack', age: 25 }
let o2 = o1
console.log(o1, o2);
o2.name = 'Rose'
console.log(o1, o2);            

淺拷貝

●說到淺拷貝就不考慮基本資料類型了

●就是按照原先的資料類型建立一個新的一樣的資料類型

●把原始資料中的每一個資料依次指派到新的資料類型中

●通過分析我們發現淺拷貝隻能拷貝一層

●并且是簡單資料類型 如果有第二層甚至多層就不能實作完完整整的複制

// 淺拷貝
// 準備原始資料
const o1 = {
    name: 'Jack',
    age: 25,
    color: {
        red: '紅色',
        blue: '藍色'
    }
}
// 實作拷貝
// 首先建立一個新的資料
const o2 = {}
// 周遊循環原始資料類型
for (let k in o1) {
    // 接下來就是把原始資料類型中的資料指派到新建立的資料類型中
    // 如果這個時候元素對象中還複雜資料類型
    // 同樣是指派 依然不能實作完完整整的複制
    o2[k] = o1[k]
}
console.log(o1, o2);
// 修改o1中的值
o1.color.red = '紅顔色'
console.log(o1, o2);            

深拷貝

●就是要百分百的拷貝一份原始資料

●修改任何裡面的資料都不會影響另一個裡面的資料

●不管層級有多深 都能完整的複制過來 兩個之間沒有關系

●這就要通過深拷貝

●深拷貝的核心:遞歸

// 準備資料
const o1 = {
    name: 'Jack',
    age: 18,
    info: {
        height: 180,
        weight: 180,
        desc: {
            message: '今天天氣很好'
        }
    },
    address: {
        city: '北京'
    },
    hobby: ['吃飯', '睡覺']
}
// 準備一個空對象
const o2 = {}
// 要實作深拷貝 我們就準備一個函數
function deepCopy(o2, o1) {
    // 首先我們還是要通過循環周遊的方式拿到原始資料類型中的資料
    for (let k in o1) {
        // 因為我們不知道裡面都有什麼資料是以我們要先判斷
        if (Object.prototype.toString.call(o1[k]) === '[object Object]') {
            // 代碼能進入到這裡說明是一個對象
            o2[k] = {}
            // 再次進行拷貝 這個過程和我們剛做的是不是一樣
            // 那我就直接調用我們的deepCopy函數就好
            deepCopy(o2[k], o1[k])
        } else if (Object.prototype.toString.call(o1[k]) === '[object Array]') {
            // 代碼能執行到這裡說明是一個數組
            o2[k] = []
            // 繼續執行我們的拷貝函數
            deepCopy(o2[k], o1[k])
        } else {
            o2[k] = o1[k]
        }
    }
}
// 使用
deepCopy(o2, o1)
console.log(o1, o2);
o1.info.height = 300
console.log(o1, o2);            

繼續閱讀