Wyszukiwanie w Google „obiektu klonowania javascript” przynosi naprawdę dziwne wyniki, niektóre z nich są beznadziejnie przestarzałe, a niektóre po prostu zbyt złożone, czyż nie jest to tak proste, jak po prostu:
let clone = {...original};
Czy jest w tym coś nie tak?
javascript
ecmascript-6
javascript-objects
Dmitry Fadeev
źródło
źródło
original = { a: [1,2,3] }
daje klon zclone.a
dosłownie bytemoriginal.a
. Modyfikacja poprzez jednąclone
luboriginal
modyfikację tego samego , więc nie, to jest złe =)Odpowiedzi:
Jest to dobre do płytkiego klonowania . Rozkład obiektów jest standardową częścią ECMAScript 2018 .
Do głębokiego klonowania potrzebujesz innego rozwiązania .
const clone = {...original}
płytkie klonowanieconst newobj = {...original, prop: newOne}
aby niezmiennie dodać kolejny rekwizyt do oryginału i zapisać jako nowy obiekt.źródło
JSON.parse(JSON.stringify(input))
JSON.parse(JSON.stringify(input))
nie zadziała, ponieważ jeśli istniejąfunctions
lubinfinity
jako wartości, po prostu przypiszenull
ich miejsce. Będzie działać tylko wtedy, gdy wartości są proste,literals
a niefunctions
.EDYCJA: Kiedy opublikowano tę odpowiedź,
{...obj}
składnia nie była dostępna w większości przeglądarek. W dzisiejszych czasach powinieneś sobie z nim radzić (chyba że musisz wspierać IE 11).Użyj Object. assign.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/ assign
Jednak to nie będzie głębokim klonem. Jak dotąd nie ma natywnego sposobu głębokiego klonowania.
EDYCJA: Jak @Mike 'Pomax' Kamermans wspomniał w komentarzach, możesz głęboko klonować proste obiekty (tj. Bez prototypów, funkcji lub odwołań cyklicznych) za pomocą
JSON.parse(JSON.stringify(input))
źródło
JSON.parse(JSON.stringify(input))
to przypadku jest właściwym głębokim klonem. Jednak w chwili, gdy w grę wchodzą prototypy, funkcje lub odwołania cykliczne, rozwiązanie to przestaje działać.Jeśli użyte metody nie działają dobrze z obiektami obejmującymi typy danych, takie jak Date , spróbuj tego
Import
_
Obiekt głęboko klonowany
źródło
import _ from 'lodash';
wystarczy. Ale +1 za odpowiedź „nie wymyślaj koła na nowo”.jeśli nie chcesz używać json.parse (json.stringify (obiekt)), możesz utworzyć rekurencyjne kopie klucz-wartość:
Ale najlepszym sposobem jest utworzenie klasy, która może zwrócić jej własny klon
źródło
Kontynuując odpowiedź @marcel, stwierdziłem, że w sklonowanym obiekcie nadal brakuje niektórych funkcji. na przykład
gdzie na MyObject mogłem sklonować metodę MethodA, ale metodaB została wykluczona. Stało się tak, ponieważ go brakuje
co oznaczało, że nie pojawił się w
Zamiast tego przeszedłem na
który będzie zawierał nie wyliczalne klucze.
Odkryłem również, że prototyp ( proto ) nie został sklonowany. W tym celu użyłem
PS: Frustrujące, że nie mogłem znaleźć wbudowanej funkcji do tego.
źródło
Możesz to również zrobić w ten sposób,
źródło
Ale Object. assign () nie tworzy głębokiego klonu
Aby to naprawić, powinniśmy użyć pętli klonowania, która sprawdza każdą wartość parametru user [klucz] i, jeśli jest to obiekt, również replikować jego strukturę. Nazywa się to „głębokim klonowaniem”.
Istnieje standardowy algorytm głębokiego klonowania, który obsługuje powyższy przypadek i bardziej złożone przypadki, zwany algorytmem klonowania strukturalnego . Aby nie wymyślać koła na nowo, możemy użyć jego działającej implementacji z biblioteki JavaScript, ponieważ metoda nazywa się _.cloneDeep (obj) .
źródło
Wszystkie powyższe metody nie obsługują głębokiego klonowania obiektów zagnieżdżonych na n poziomach. Nie sprawdzałem jego działania na tle innych, ale jest krótki i prosty.
Pierwszy przykład poniżej przedstawia klonowanie obiektów przy użyciu klonowania
Object.assign
tylko do pierwszego poziomu.Korzystając z poniższego podejścia do obiektu głębokich klonów
źródło