JavaScript中的深淺拷貝

深淺拷貝

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

從上面的例子能夠發現,若是給一個變量賦值一個對象,那麼二者的值會是同一個引用,其中一方改變,另外一方也會相應改變。javascript

解決這個問題,能夠引入淺拷貝:java

淺拷貝

  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

這樣說明淺拷貝並無對嵌套的對象生效。此時須要深拷貝上場:code

深拷貝

深拷貝最簡單的實現辦法就是使用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

可是當出現如下幾種狀況的時候,會出現問題:ip

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

報錯了,不能解決循環引用對象的問題。ci

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

發現只拷貝了name ,而忽略了undefinedfuncionget

因此,JSON.parse(JSON.stringify(obj))遇到這幾種狀況會出現問題:string

  • 不會拷貝 undefined
  • 不能拷貝函數
  • 不能解決循環引用的對象

因此採用下面的方式:io

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"}
相關文章
相關標籤/搜索