JavaScript的深淺拷貝

什麼是深淺

概念

深拷貝、淺拷貝只針對像Object/Array這樣的對象,對於基本類型而言,能夠理解爲是沒有深淺的區別的。javascript

淺拷貝複製的是引用,修改對象的屬性,會彼此影響。java

just like this數組

let a = {name: 'ziv'}
let b = a // a和b指向了同一塊內存
b.name = 'lucky'
console.log(a.name) // 'lucky'
console.log(b.name) // 'lucky'

深拷貝從新開闢了一個空間,修改對象的屬性,彼此不會影響。函數

實現淺拷貝

使用內置的方法

// Object.assign()
//只能用於淺拷貝對象或者合併對象
let obj = {a:'x', b: {c: 'y'}}
let newObj = Object.assign({}, obj)
obj.b.c = 'z'
console.log(newObj) // {a:"x", b: {c: "z"}}

// Array.from() 
// ...操做符
// slice()
// concat() 用於數組

let arr = [1,2, [3,4,5]]
let sliceArr = arr.slice()
let concatArr = arr.concat()
let fromArr = Array.from(arr)
let newArr = [...arr]

arr[2][1] = 'sixsix'

console.log(sliceArr) // [1,2,[3,'sixsix',5]]
console.log(concatArr) // [1,2,[3,'sixsix',5]]
console.log(fromArr) // [1,2,[3,'sixsix',5]]

使用遍歷

// 對象淺拷貝
let shallowCopy = function(obj) {
    // 若是不是對象,不執行拷貝
    if (typeof obj !== 'object') return 
    // 判斷對象是數組仍是對象
    let newObj = obj instanceof Array ? [] : {}
    // 遍歷obj
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            // 拷貝到新對象中
            newObj[key] = obj[key]
        }
    }
    return newObj
}

實現深拷貝

序列化反序列化

// 適用於數組還有對象,可是對於函數對象、正則對象、稀疏數組等沒法進行深拷貝(並且會直接丟失相應的值),而且會拋棄對象的constructor,也就是說不管這個函數的構造函數是誰,使用這種拷貝以後,constructor都會變成Object。對循環引用一樣沒法處理。
let arr = ['old', 1, true, ['old1', 'old2'], {old: 1}]

let new_arr = JSON.parse(JSON.stringify(arr))
arr[3][0] = 'new1' // new_arr並不會更改
console.log(new_arr)

使用遞歸

// 適用於對象裏面有對象
let deepCopy = function(obj) {
    if (typeof obj !== 'object') return obj
    let newObj = obj instanceof Array ? [] : {}
    
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]
        }
    }
    return newObj
}
相關文章
相關標籤/搜索