js 物件拷貝的三種方法
阿新 • • 發佈:2020-08-28
js 物件拷貝的三種方法
以下面資料格式obj 為主:
const obj = {
data: 1,
un: undefined,
info: {
d: 2
},
fn: function() {
console.log('Function')
},
get c() {
return info.d
}
}
Object.assign
const ObjA = Object.assign({}, obj) ObjA.data = 'a' ObjA.info.d = 'b' const ObjB = Object.assign({}, obj) ObjB.data = 'c' ObjB.info.d = 'd' console.log(ObjA) console.log(ObjB) /* ==========輸出========== { data: 'a', info: { d: 'd' }, un: undefined, fn: [Function: fn] } { data: 'c', info: { d: 'd' }, un: undefined, fn: [Function: fn] } */
我們會發現info.d
內容相等,說明Object.assign
無法拷貝深層次內容,適用於淺層拷貝。
JSON.stringify & JSON.parse
const ObjA = JSON.parse(JSON.stringify(obj)) ObjA.data = 'a' ObjA.info.d = 'b' const ObjB = JSON.parse(JSON.stringify(obj)) ObjB.data = 'c' ObjB.info.d = 'd' console.log(ObjA) console.log(ObjB) /* ==========輸出========== { data: 'a', info: { d: 'b' }, c: 2 } { data: 'c', info: { d: 'd' }, c: 2 } */
我們將源物件轉換為字串,再轉換為新物件雖然解決了深層次拷貝的問題,但我們會發現物件中的Function
和undefined
無法拷貝,並且將c: [Getter] 直接轉換成了鍵值對 c:2。
Object.create
const ObjA = Object.create(obj) ObjA.data = 'a' ObjA.info.d = 'b' const ObjB = Object.create(obj) ObjB.data = 'c' ObjB.info.d = 'd' console.log(ObjA) console.log(ObjB) console.log(ObjA.__proto__) console.log(ObjB.__proto__) /* ==========輸出========== { data: 'a' } { data: 'c' } { data: 1, info: { d: 'd' }, fn: [Function: fn], c: [Getter] } { data: 1, info: { d: 'd' }, fn: [Function: fn], c: [Getter] } */
Object.create 原型鏈繼承,也可以達到內容淺層拷貝。
總結:
賦值 | 淺層拷貝 | 深層拷貝 | getter/setter |
---|---|---|---|
Object.assign | ok | no | no |
JSON.stringify | ok | ok | no |
Object.create | ok | no | ok |