JavaScript中的深淺拷貝

深淺拷貝

let a = {
    age: 1
}
let b = a
a.age = 2
console.log(b.age) // 2

從上面的例子可以發(fā)現(xiàn),如果給一個變量賦值一個對象,那么兩者的值會是同一個引用,其中一方改變,另一方也會相應改變。

解決這個問題,可以引入淺拷貝:

淺拷貝

  1. 可以使用Object.assign 來解決這個問題
let a = {
    age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1
  1. 使用ES6展開運算符(...)解決
let a = {
    age: 1
}
let b = {...a}
a.age = 2
console.log(b.age) // 1

通常淺拷貝能解決大部分的問題,但是當遇到,對象里面嵌套一個對象的時候,就需要用到深拷貝了

let a = {
    age: 1,
    name: {
        first: 'black'
    }
}
let = {...a}
a.name.first = 'guyue'
console.log(b.name.first) // guyue

這樣說明淺拷貝并沒有對嵌套的對象生效。此時需要深拷貝上場:

深拷貝

深拷貝最簡單的實現(xiàn)辦法就是使用JSON.parse(JSON.stringify(object)) 來解決。

let a = {
    age: 1,
    name: {
        first: 'black'
    }
}
let b = JSON.parse(JSON.stringify(a))
a.name.first = 'guyue'
console.log(b.name.first) // black

但是當出現(xiàn)以下幾種情況的時候,會出現(xiàn)問題:

let obj = {
    a: 1,
    b: {
        c: 2
    }
}
obj.c = obj.b
obj.d = obj.a
obj.b.c = obj.c
let newObj = JSON.parse(JSON.stringify(obj))
console.log(newObj)
// Uncaught TypeError: Converting circular structure to JSON

報錯了,不能解決循環(huán)引用對象的問題。

let obj = {
    age: undefined,
    sex: function(){},
    name: 'black'
}
let newObj = JSON.parse(JSON.stringify(obj))
console.log(newObj) // {name: "black"}

發(fā)現(xiàn)只拷貝了name,而忽略了undefinedfuncion。

所以,JSON.parse(JSON.stringify(obj))遇到這幾種情況會出現(xiàn)問題:

  • 不會拷貝 undefined
  • 不能拷貝函數(shù)
  • 不能解決循環(huán)引用的對象

所以采用下面的方式:

function deepClone(obj) {
    let res = obj instanceof Array ? [] : {}
    for(let k in obj) {
        res[k] = obj[k]
        if(typeof obj[k] === Object) {
            deepClone(obj[k])
        }
    }
    return res
}

let obj = {
    age: undefined,
    sex: function(){},
    name: 'black'
}

let newObj = deepClone(obj)
console.log(newObj) // {age: undefined, sex: ?, name: "black"}

可以采用ES2017的新語法:

function copyObject(orig) {
  return Object.create(
    Object.getPrototypeOf(orig),
    Object.getOwnPropertyDescriptors(orig)
  );
}

let obj = {
    age: undefined,
    sex: function(){},
    name: 'black'
}

let newObj = copyObject(obj)
console.log(newObj) // {age: undefined, sex: ?, name: "black"}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容