Powiedzmy, że mam options
zmienną i chcę ustawić wartość domyślną.
Jaka jest korzyść / wada tych dwóch alternatyw?
Korzystanie z rozkładania obiektów
options = {...optionsDefault, ...options};
Lub używając Object.assign
options = Object.assign({}, optionsDefault, options);
To zatwierdzenie sprawiło, że się zastanawiałem.
javascript
ecmascript-6
Olivier Tassinari
źródło
źródło
Odpowiedzi:
To niekoniecznie jest wyczerpujące.
Rozłóż składnię
Zalety:
Jeśli tworzysz kod do wykonania w środowiskach bez natywnej obsługi, możesz po prostu skompilować tę składnię (w przeciwieństwie do korzystania z funkcji wypełniania wielokrotnego). (Na przykład z Babel.)
Mniej gadatliwy.
Niedogodności:
Kiedy pierwotnie napisano tę odpowiedź, była to propozycja , która nie była znormalizowana. Korzystając z propozycji, zastanów się, co byś zrobił, gdybyś napisał z nim teraz kod, który nie jest standaryzowany ani nie zmienia się w miarę zbliżania się do normalizacji. Od tego czasu została znormalizowana w ES2018.
Dosłowne, a nie dynamiczne.
Object.assign()
Zalety:
Standaryzowany.
Dynamiczny. Przykład:
Niedogodności:
To nie jest bezpośrednio związane z tym, o co pytasz. Ten kod nie był używany
Object.assign()
, tylko kod użytkownika (object-assign
), który robi to samo. Wygląda na to, że kompilują ten kod z Babelem (i łączą go z Webpackiem), o tym właśnie mówiłem: składnię, którą można po prostu skompilować. Najwyraźniej woleli to od uwzględnieniaobject-assign
jako zależności, która byłaby częścią ich kompilacji.źródło
Object.assign()
. Lub możesz ręcznie iterować tablicę obiektów i ich własnych rekwizytów ręcznie przypisując je do celu i sprawiając, że będzie jeszcze bardziej gadatliwy: PW przypadku obiektu referencyjnego odpoczynek / rozkład jest finalizowany w ECMAScript 2018 jako etap 4. Propozycję można znaleźć tutaj .
W większości przypadków resetowanie i rozkładanie obiektów działa w ten sam sposób, kluczową różnicą jest to, że rozkład definiuje właściwości, a Object.assign () je ustawia . Oznacza to, że Object.assign () wyzwala ustawiacze.
Warto pamiętać, że poza tym reszta obiektu / rozkład 1: 1 odwzorowuje na Object.assign () i działa inaczej niż rozkład tablic (iterowalny). Na przykład przy rozkładaniu tablicy rozkładane są wartości zerowe. Jednak przy użyciu rozkładania obiektów wartości zerowe są po cichu rozkładane na nic.
Przykład rozprzestrzeniania się macierzy (iterowalnej)
Przykład rozprzestrzeniania się obiektu
Jest to zgodne ze sposobem działania Object.assign (), oba po cichu wykluczają wartość zerową bez błędu.
źródło
Object.assign
użycie seterów.Object.assign({set a(v){this.b=v}, b:2}, {a:4}); // {b: 4}
vs.{...{set a(v){this.b=v}, b:2}, ...{a:4}}; // {a: 4, b: 2}
const x = {c: null};
. W takim przypadku, AFAIK, chcielibyśmy zobaczyć zachowanie jak tablicy://{a: 1, b: 2, c: null}
.Myślę, że jedną wielką różnicą między operatorem rozprzestrzeniania i
Object.assign
tym, o którym nie wspominają obecne odpowiedzi, jest to, że operator rozprzestrzeniania nie skopiuje prototypu obiektu źródłowego do obiektu docelowego. Jeśli chcesz dodać właściwości do obiektu i nie chcesz zmieniać jego instancji, musisz użyćObject.assign
. Poniższy przykład powinien to wykazać:źródło
errorExtendedUsingAssign === error
, aleerrorExtendedUsingSpread
jest nowy obiekt (a prototyp nie został skopiowany).let target = Object.create(source); Object.assign(target, source);
Jak wspomnieli inni, w tym momencie pisania,
Object.assign()
wymaga wypełnienia, a rozprzestrzenianie się obiektów...
wymaga transpilacji (i być może również wypełnienia), aby działało.Rozważ ten kod:
Oba wytwarzają tę samą moc wyjściową.
Oto dane wyjściowe z Babel do ES5:
To moje dotychczasowe zrozumienie.
Object.assign()
jest w rzeczywistości znormalizowany, a ponieważ rozprzestrzenianie się obiektów...
nie jest jeszcze. Jedynym problemem jest obsługa przeglądarek dla tych pierwszych, aw przyszłości także dla tych drugich.Graj tutaj kodem
Mam nadzieję że to pomoże.
źródło
{}
powinno naprawić niespójność.Operator rozkładania obiektów (...) nie działa w przeglądarkach, ponieważ nie jest jeszcze częścią żadnej specyfikacji ES, tylko propozycją. Jedyną opcją jest skompilowanie go z Babel (lub czymś podobnym).
Jak widać, to po prostu cukier składniowy nad Object.assign ({}).
O ile widzę, są to ważne różnice.
...
dla obiektów nie jest znormalizowany...
chroni cię przed przypadkowym mutowaniem obiektu...
polifill Object. przypisze do przeglądarki bez niego...
potrzebuje mniej kodu, aby wyrazić ten sam pomysłźródło
Object.assign
, ponieważ operator rozkładania zawsze da ci nowy obiekt.Chciałbym podsumować stan funkcji ES „rozprzestrzeniania obiektów rozproszonych” w przeglądarkach i ekosystemie za pomocą narzędzi.
Spec
Przeglądarki: wkrótce w Chrome, SF, Firefox (wersja 60, IIUC)
Narzędzia: Węzeł 8.7, TS 2.1
Spinki do mankietów
Próbka kodu (podwaja się jako test zgodności)
Ponownie: w momencie pisania tego przykładu próbka działa bez transpilacji w Chrome (60+), Firefox Developer Edition (wersja zapoznawcza Firefox 60) i Node (8.7+).
Po co odpowiadać?
Piszę to 2,5 roku po pierwotnym pytaniu. Ale miałem to samo pytanie i właśnie tutaj wysłał mnie Google. Jestem niewolnikiem misji SO, aby poprawić długi ogon.
Ponieważ jest to rozszerzenie składni „rozprzestrzeniania się macierzy”, bardzo trudno było google i trudno znaleźć w tabelach zgodności. Najbliższe, jakie mogłem znaleźć, to „rozpiętość właściwości” Kangaxa , ale ten test nie ma dwóch rozkładów w tym samym wyrażeniu (nie scalenia). Poza tym nazwa na stronach statusu propozycji / wersji roboczych / przeglądarki używa „właściwości spread”, ale wydaje mi się, że była to „pierwsza zasada”, do której doszła społeczność po propozycjach użycia składni spreadu do „scalania obiektów”. (Co może wyjaśniać, dlaczego tak trudno jest google.) Więc dokumentuję tutaj moje odkrycie, aby inni mogli przeglądać, aktualizować i kompilować linki dotyczące tej konkretnej funkcji. Mam nadzieję, że się uda. Proszę o pomoc w rozpowszechnianiu wiadomości o lądowaniu w specyfikacji oraz w przeglądarkach.
Na koniec dodałbym te informacje jako komentarz, ale nie mogłem ich edytować bez naruszenia pierwotnych intencji autorów. W szczególności nie mogę edytować komentarza @ ChillyPenguin bez utraty jego zamiaru poprawienia @RichardSchulte. Ale lata później Richard miał rację (moim zdaniem). Dlatego piszę tę odpowiedź, mając nadzieję, że w końcu zyska przyczepność do starych odpowiedzi (może to potrwać lata, ale przecież o to chodzi w efekcie długiego ogona ).
źródło
UWAGA: Spread to NIE tylko cukier składniowy wokół Object.assign. Działają znacznie inaczej za kulisami.
Object.assign stosuje ustawiacze do nowego obiektu, Spread nie. Ponadto obiekt musi być iterowalny.
Kopiuj Użyj tej opcji, jeśli potrzebujesz wartości obiektu w tej chwili i nie chcesz, aby ta wartość odzwierciedlała wszelkie zmiany wprowadzone przez innych właścicieli obiektu.
Skorzystaj z niego, aby utworzyć płytką kopię obiektu. Dobra praktyka, aby zawsze ustawiać niezmienne właściwości do kopiowania - ponieważ wersje zmienne mogą być przekazywane do niezmiennych właściwości, kopiowanie zapewni, że zawsze będziesz mieć do czynienia z niezmiennym obiektem
Przypisz Przypisz jest w pewnym stopniu przeciwieństwem kopiowania. Przypisanie wygeneruje obiekt ustawiający, który przypisuje wartość do zmiennej instancji bezpośrednio, zamiast kopiować lub zachowywać ją. Podczas wywoływania obiektu pobierającego właściwość przypisania zwraca odwołanie do rzeczywistych danych.
źródło
Inne odpowiedzi są stare, nie można uzyskać dobrej odpowiedzi.
Poniższy przykład dotyczy literałów obiektowych, pomaga, jak oba mogą się uzupełniać i jak nie mogą się uzupełniać (dlatego różnica):
Kilka innych małych przykładów tutaj, także dla tablicy i obiektu:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
źródło
Jest to teraz część ES6, dlatego jest znormalizowana i jest również udokumentowana w MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
Jest bardzo wygodny w użyciu i ma wiele sensu obok niszczenia obiektów.
Jedyną pozostałą zaletą wymienioną powyżej są dynamiczne możliwości Object.assign (), jednak jest to tak proste, jak rozkładanie tablicy wewnątrz dosłownego obiektu. W skompilowanym wyjściu Babel używa dokładnie tego, co pokazano w Object.assign ()
Tak więc poprawną odpowiedzią byłoby użycie rozproszenia obiektów, ponieważ jest on teraz znormalizowany, szeroko stosowany (patrz reaguj, redux itp.), Jest łatwy w użyciu i ma wszystkie funkcje Object.assign ()
źródło
Chciałbym dodać ten prosty przykład, gdy musisz użyć Object.assign.
Nie może być jasne, gdy używasz JavaScript. Ale dzięki TypeScript łatwiej jest utworzyć instancję jakiejś klasy
źródło