1. 程式人生 > 實用技巧 >JavaScript之淺談深拷貝與淺拷貝

JavaScript之淺談深拷貝與淺拷貝

這一章我們聊一下js中深拷貝與淺拷貝

深拷貝和淺拷貝的區別?

1.淺拷貝: 將原物件或原陣列的引用直接賦給新物件,新陣列,新物件/陣列只是原物件的一個引用

2.深拷貝: 建立一個新的物件和陣列,將原物件的各項屬性的“值”(陣列的所有元素)拷貝過來,是“值”而不是“引用”

為什麼要使用深拷貝?

我們希望在改變新的陣列(物件)的時候,不改變原陣列(物件)

接下來我們用程式碼演示一下深拷貝與淺拷貝?(一定要自己動手敲一遍)

 var obj = {
        name: 'xiaoming',
        age: 18,
        friends: ['xiaozhang', 'zhaosi', 'wangwu'],
        girlfriend: {
            name: 'xiaomei',
            age: 16,
            friend: ['xiaohong', 'cuisan', 'lili']
        }
    }
 var obj1 = {}

這裡我們定義了一個物件obj和一個空物件obj1,我們的目的是要把obj的內容拷貝到obj1中

淺拷貝

function copy(a, b) {
        for (var attr in a) { //遍歷a物件裡面的每一個屬性
            b[attr] = a[attr] //把a物件裡面的屬性儲存到b物件裡面
        }
    }
    copy(obj, obj1)
    console.log(obj)
    console.log(obj1)

執行結果:

從結果我們可以看到,打印出來的obj和obj1是完全一樣的

然後我們分別修改obj中原始值和引用型別的值:

obj.age = 30 // 修改了obj的age值
obj.friends.splice(0, 1) //刪除陣列中第一個元素

此時的執行結果:

我們看到obj的age值變成了30,obj1的值依然是18,而我們刪除了obj中friends陣列的第一個元素時,obj1的friends陣列中的第一個元素也被刪除了
這不是我們希望看到的結果

解決辦法:

深拷貝

function deepCopy(a, b) {
        for (var attr in a) {
            var item = a[attr]
            if (item instanceof Array) {
                b[attr] = []
                deepCopy(item, b[attr])
            } else if (item instanceof Object) {
                b[attr] = {}
                deepCopy(item, b[attr])
            } else {
                b[attr] = item
            }
        }
    }
    deepCopy(obj, obj1)
    obj.girlfriend.friend.splice(0, 1)
    console.log(obj)
    console.log(obj1)

instanceof用法點這裡

執行結果:

這樣就可以只改變obj中的陣列而不改變obj1中的陣列

參考資料

1.CSDN部落格:https://blog.csdn.net/wyp1725726792/article/details/102756183
2.2.阮一峰 《ECMASript6入門》 http://es6.ruanyifeng.com/