2016-09-28 10 views
39

Googling dla „obiektu javascript klonu” przynosi pewne bardzo dziwne wyniki, niektóre z nich są beznadziejnie przestarzałe, a niektóre są po prostu zbyt skomplikowane, nie jest to tak proste, jak tylko:Czy to dobry sposób na klonowanie obiektu w ES6?

let clone = {...original}; 

Czy jest coś złego w tym ?

+0

Twój przykład jest nieprawidłowy javascript, przy okazji. –

+0

To nie jest legalne ES6. Ale jeśli tak nie było, nie jest to klon: zarówno twój klon jak i oryginalne właściwości wskazują na to samo teraz. Na przykład 'original = {a: [1,2,3]}' daje ci klon z 'clone.a' dosłownie będący' original.a'. Modyfikacja poprzez 'clone' lub' original' modyfikuje * to samo *, więc nie, to jest złe =) –

+0

@AlbertoRivera To * trochę * poprawny JavaScript, ponieważ jest to [etap 2] (https: // github. com/sebmarkbage/ecmascript-rest-spread), która prawdopodobnie będzie przyszłym dodatkiem do standardu JavaScript. – Frxstrem

Odpowiedz

47

całkowicie do przyjęcia, że ​​teraz nawet moreso object spread is stage 3. Ludzie ponad komplikują rzeczy.

const clone = {...original} sklonować

const newobj = {...original, prop: newOne} do immutably dodać inny rekwizyt do oryginału i sklepie jako nowy obiekt.

36

Użyj 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 } 

Jednak to nie będzie głębokie klon. Nie ma jeszcze rodzimej metody głębokiego klonowania.

EDIT: Jak @Mike „Pomax” Kamermans wspomniano w komentarzach, można głęboko sklonować prostych obiektów za pomocą JSON.parse(JSON.stringify(input))

+8

Jest jeden, pod warunkiem, że obiekt jest prawdziwym obiektem literalnym i czysto danych, w którym to przypadku 'JSON.parse (JSON.stringify (input))' jest prawidłowym głębokim klonem. Jednak w momencie, gdy prototypy, funkcje lub odwołania cykliczne są w grze, to rozwiązanie już nie działa. –

+0

@ Mike'Pomax'Kamermans To prawda. Utrata funkcjonalności dla pobierających i ustawiających jest okropna, choć ... –

+0

Jeśli potrzebujesz ogólnej funkcji do głębokiego klonowania dowolnego obiektu, sprawdź http://stackoverflow.com/a/13333781/560114. –

0

Należy używać tylko ... (spread (czyli nie prototypy, funkcji lub odwołania okrągłe).) na iterabelach, używanie spreadu na non iterables lub wewnątrz literału obiektowego spowoduje błąd. Poprzednia odpowiedź to rozwiązanie. Można również sklonować z więcej niż jednego przedmiotu

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

jeśli nie chcesz używać JSON.parse (JSON.stringify (Object)) można utworzyć wielokrotnie kopiuje klucz-wartość:

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; 
} 

ale najlepszym sposobem jest, aby utworzyć klasę, która może zwróć klona to self

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) } 
} 
Powiązane problemy