2016-09-28 64 views
39

谷歌搜索「的JavaScript對象克隆」帶來一些非常奇怪的結果,其中有些是完全過時的,有些是太複雜了,不是那麼容易,因爲剛:這是克隆ES6中對象的好方法嗎?

let clone = {...original}; 

這有什麼不對的?

+0

您的示例是不正確的JavaScript,順便說一下。 –

+0

這是不合法的ES6。但如果沒有,這不是一個克隆:克隆和原始屬性現在都指向相同的東西。例如'original = {a:[1,2,3]}'給你一個克隆,其中'clone.a'實際上是'original.a'。通過'clone'或'original'修改*相同的東西*,所以不,這是不好的=) –

+0

@AlbertoRivera它是* kinda *有效的JavaScript,因爲它是[stage 2](https:// github。 com/sebmarkbage/ecmascript-rest-spread)提案,這很可能是未來對JavaScript標準的補充。 – Frxstrem

回答

47

完全可以接受的,甚至moreso現在object spread is stage 3克隆。人們過於複雜的事情。

const clone = {...original}克隆

const newobj = {...original, prop: newOne}到不可改變添加其他道具原來並存儲爲一個新的對象。

36

使用Object.assign。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

var obj = { a: 1 }; 
var copy = Object.assign({}, obj); 
console.log(copy); // { a: 1 } 

但是,這不會讓深克隆。到目前爲止還沒有深入克隆的本地方式。

編輯:由於@Mike「Pomax」 Kamermans在評論中提到的,你可以深刻的克隆簡單對象使用JSON.parse(JSON.stringify(input))

+8

有一個,提供你的對象是一個真正的對象字面值,純粹是數據,在這種情況下'JSON.parse(JSON.stringify(input))'是一個適當的深度克隆。但是,當原型,函數或循環引用出現時,該解決方案不再有效。 –

+0

@ Mike'Pomax'Kamermans確實如此。丟失吸氣劑和吸附劑的功能是可怕的,但... –

+0

如果您需要通用功能來深入克隆任何對象,請參閱http://stackoverflow.com/a/13333781/560114。 –

0

您應該只使用...(展開(即沒有原型,功能或循環引用。) )在iterables上,在非迭代中或在對象文本中使用傳播會引發錯誤。以前的答案是解決方案。您還可以從多個對象

let obj1 = { firstDay: 'monday' } 
let obj2 = { secondDay: 'tuesday' } 
let obj3 = { thirdDay: 'thirdDay' } 

let clone = Object.assign({},obj1,obj2,obj3) 
console.log(clone) 
// { firstDay: 'monday', 
// secondDay: 'tuesday', 
// thirdDay: 'thirdDay' } 
0

,如果你不希望使用json.parse(json.stringify(對象)),你可以創建遞歸鍵值副本:

function copy(item){ 
    let result = null; 
    if(!item) return result; 
    if(Array.isArray(item)){ 
    result = []; 
    item.forEach(element=>{ 
     result.push(copy(element)); 
    }); 
    } 
    else if(item instanceof Object && !(item instanceof Function)){ 
    result = {}; 
    for(let key in item){ 
     if(key){ 
     result[key] = copy(item[key]); 
     } 
    } 
    } 
    return result || item; 
} 

但最好的方式是創建一個類,它可以返回它的自我克隆

class MyClass{ 
    data = null; 
    constructor(values){ this.data = values } 
    toString(){ console.log("MyClass: "+this.data.toString(;) } 
    remove(id){ this.data = data.filter(d=>d.id!==id) } 
    clone(){ return new MyClass(this.data) } 
}