Sådan flettes objekter med objektspredningsoperatøren

Lad os sige, at vi har en applikation, hvor vi vil oprette en bruger, når de tilmelder sig.

En bruger vil se sådan her ud og består af en række egenskaber, deres navn, deres brugernavn, deres telefonnummer, deres e-mail og deres adgangskode:

const user = {
  name: "",
  username: "",
  phoneNumber: "",
  email: "",
  password: "",
};

Og lad os sige, at når en bruger tilmelder sig, behøver de ikke at give alle disse data på én gang. Dette er standard for de fleste applikationer - for at gøre det nemt for folk at komme igennem skal de blot udfylde et par nødvendige felter såsom deres brugernavn, e-mail og adgangskode. Vi lader brugere udfylde disse ikke-påkrævede felter som deres telefonnummer og navn, efter at de har oprettet en konto.

En bruger udfylder formularen og giver os disse nødvendige værdier. Vi gemmer dem på et objekt kaldet newUser :

const newUser = {
  username: "ReedBarger",
  email: "[email protected]",
  password: "mypassword",
};

Hvordan bruger vi alle disse data på newUser-objektet, men bruger stadig brugeren som vores model?

Det betyder, at vi ønsker at flette disse to objekter, så vi får alle fem egenskaber, der er nødvendige for hver bruger, inklusive de tomme værdier for name og phoneNumber .

At oprette et nyt objekt, der bevarer vores standardegenskaber på brugerobjektet, mens det flettes med nye data, er muligt med en ny objektmetode kaldet Object.assign .

Object.assign() lader dig opdatere et objekt med egenskaber fra et andet objekt.

Sådan fungerer Object.assign

Det første objekt, som vi sender til Object.assign er det objekt, som vi ønsker skal returneres.

For alle andre argumenter er det objekter, som vi ønsker at flette ind i det første objekt. Det vil sige, at vi vil tage deres egenskaber og sætte dem på det første objekt. Hvis egenskaber for andre objekter har samme navn som det første, som det er tilfældet med username , email og password , vil deres værdier blive tilføjet til det originale objekt.

Så baseret på det, vi nu ved om Object.assign, hvad tror du resultatet bliver?

Object.assign(user, newUser); 

// {name: "", username: "ReedBarger", phoneNumber: "", email: "[email protected]", password: "mypassword"}

Vi får et objekt med de samme nøgler som vores oprindelige brugerobjekt, men hvis værdier er opdateret. Specifikt værdierne for username , email og password .

Hvorfor? Fordi newUser havde de samme egenskaber som user , og siden de blev slået sammen til user , blev de oprindelige værdier overskrevet.

Nem at mutere data med Object.assign

Der er dog et problem med Object.assign() som vi bruger det i øjeblikket. Vi kan se det, hvis du fjerner console.log, men stadig udfører Object.assign og log derefter det originale brugerobjekt bagefter.

// Object.assign(user, newUser);

user; // {name: "", username: "ReedBarger", phoneNumber: "", email: "[email protected]", password: "mypassword"}

Det, der sker, er, at Object.assign muterer vores oprindelige brugerobjekt.

Objekter sendes ved reference og ikke efter værdi. Som et resultat kan vi få uventede fejl som denne.

For at rette op på dette ønsker vi ikke at flette nye værdier sammen med den originale user objekt, men brug i stedet et helt nyt objekt. Vi kan oprette som det første argument til Object.assign et helt nyt objekt, der skal opdateres og derefter returneres, og derefter flette dataene fra user ind og derefter newUser :

Object.assign({}, user, newUser); 

// {name: "", username: "ReedBarger", phoneNumber: "", email: "[email protected]", password: "mypassword"}

Det returnerede objekt har de korrekte værdier som før, men hvis vi nu kigger igen på den originale user objekt, det bevarer sine oprindelige værdier:

user; // {name: "", username: "", phoneNumber: "", email: "", password: ""}

Vær opmærksom på, at for at undgå at opdatere eller mutere, som det kaldes, vores originale data, skal du sende et tomt objekt som det objekt, der skal returneres fra Object.assign .

Fletning af mange objekter med Object.assign()

Dette er et almindeligt problem, som Object.assign hjælper os med meget, når du har et objekt med værdier, men mangler nogle nøgle-værdi-par. Som et resultat skal vi udfylde de resterende felter ved hjælp af et standardobjekt, i dette tilfælde bruger.

Object.assign kan flette så mange objekter, som vi vil, til det første objekt. Lad os f.eks. sige, at vi ønsker at tilføje en bekræftet ejendom til hver bruger, der som standard er falsk, for at angive, at deres e-mail, som de har angivet til tilmelding, ikke er bekræftet endnu:

Hvordan ville vi gøre det? Tag et øjeblik og prøv at flette en sådan egenskab på brugerobjektet på egen hånd...

Vi kunne oprette et nyt objekt, f.eks. et kaldet defaultStatus , eller sådan noget, hvor egenskaben verified er falsk:

const defaultStatus = {
  verified: false,
};

Og hvis vi tilføjer det som et fjerde argument -

Object.assign({}, user, newUser, defaultStatus); 

// { email: "[email protected]", name: "", password: "mypassword", phoneNumber: "", username: "ReedBarger", verified: false }

Dette vil virke.

Men i dette tilfælde er det lidt renere at tilføje objektet inline uden at erklære det som en variabel. Vær opmærksom på, at du kan gøre det for små genstande som denne:

// const defaultStatus = {
// verified: false
// }

Object.assign({}, user, newUser, { verified: false }); 

// { email: "[email protected]", name: "", password: "mypassword", phoneNumber: "", username: "ReedBarger", verified: false }

Og dette fungerer nøjagtigt det samme.

For at gennemgå er alt, hvad Object.assign er ansvarlig for at gøre, at samle objektegenskaber og indsætte det i et nyt objekt.

Men som du kan se, er arbejdet med Object.assign ikke særlig intuitivt. Det er mærkeligt at skulle passere den første tomme genstand ind for at undgå utilsigtede mutationer. Og også fra et læsbarhedssynspunkt er det ikke klart, når vi ser på denne linje, hvad der sker er, at vi skaber et objekt ud fra andre objekter og egenskaber. Vi ved ikke lige, hvad .assign-metoden gør fra første øjekast.

Introduktion til objektspredningsoperatoren

I stedet for at bruge Object.assign , kunne vi ikke bare fortælle JavaScript, at vi vil tage alle egenskaberne fra et objekt og indsætte et nyt i det.

Så lad os starte med at oprette en ny variabel kaldet createdUser at gemme vores endelige brugerdata. Og vi vil bare sætte dette lig med et objekt:

const createdUser = {};

Nu vil vi fortælle JS, at vi bare vil hente alle egenskaberne fra brugerobjektet og derefter sprede dem ind i dette nye objekt.

const createdUser = { user };

Og så efter brugerdataene, for at indsætte de nye brugerdata:

const createdUser = { user, newUser };

Og til sidst, i stedet for at levere et objekt, sætter vi bare den egenskab, vi skal bruge til sidst:verified indstillet til falsk:

const createdUser = { user, newUser, verified: false };

Men med denne syntaks ved vi, at vi kommer til at skabe indlejrede objekter på egenskaberne user og newUser . Hvordan kan vi bare fortælle JS at sprede alle egenskaberne fra et objekt til et nyt?

I ES2018 ankom en sådan funktion for at gøre netop det, kaldet objektspredningsoperatoren.

For at sprede et objekts egenskaber til et andet, skal vi blot inkludere denne syntaks ... før objektet. Vi gør det til både user og newUser . Og hvis vi logger dette:

const createdUser = { ...user, ...newUser, verified: false };

createdUser; // { email: "[email protected]", name: "", password: "mypassword", phoneNumber: "", username: "ReedBarger", verified: false }

Vi ser, at vi får det samme nøjagtige resultat som med Object.assign . Da det er tilfældet, ved vi, at spredningsoperatøren fungerer effektivt på samme måde - den fusionerer de egenskaber, der kommer senere (efter hvert komma) med egenskaberne angivet i begyndelsen. Det gør det også på en uforanderlig måde.

Med objektspredningsoperatoren har vi alle fordelene ved Object.assign() med reduceret syntaks og til at skabe objekter på en mere intuitiv måde.

Orden har betydning med Object.assign() og spread-operatoren

En sidste bemærkning er, at rækkefølgen har betydning for begge Object.assign og spredningsoperatøren. Hvis du tilføjer en værdi med den samme nøgle, vil den bruge den værdi, der er erklæret sidst.

Lad os sige, at vi for eksempel opdaterer vores oprindelige brugerobjekt til at inkludere verified ejendom. Men her verified er som standard sat til sand. Hvis vi konsolloger vores createdUser igen, hvad vil den endelige værdi af verificeret være på den?

const user = {
  name: "",
  username: "",
  phoneNumber: "",
  email: "",
  password: "",
  verified: true,
};
const createdUser = { ...user, ...newUser, verified: false };

createdUser; // { email: "[email protected]", name: "", password: "mypassword", phoneNumber: "", username: "ReedBarger", verified: false }

Vi ser at verified er falsk. Det skyldes, at den sidste værdi, en ejendom leveres, er den, som det oprettede objekt er forsynet med. Så siden verified blev sat til false i slutningen, derfor havde den i sidste ende værdien false.

Når du udfører opdateringer af eksisterende egenskaber, skal du som regel sørge for at angive opdateringsværdier i slutningen, eller i det mindste efter de eksisterende.

Resumé

I denne artikel har vi dækket både Object.assign og objektspredningsoperatøren. De gør begge det samme, men generelt er objektspredningen meget mere ligetil at bruge, da det er mere tydeligt, at vi bare skaber et grundlæggende objekt.

Du har en tendens til at se det meget oftere end Object.assign og jeg vil anbefale dig at bruge objektet spredt størstedelen af ​​tiden i din kode. Der er ingen væsentlig fordel, som Object.assign har i forhold til det.

Og også dækkede vi begge vigtige use-cases for Object.assign og objektspredningen:

  1. Brug dem til at etablere fælles standardegenskaber for ethvert objekt ved at flette to eller flere objekter. Og
  2. For ikke-destruktivt at kunne opdatere eller tilføje egenskaber. Så vi så, hvordan man opdaterer det endelige objekt med egenskaben 'verificeret' på en måde, der ikke muterede vores oprindelige brugerobjekter.

Kan du lide dette indlæg? Deltag i The React Bootcamp

React Bootcamp tager alt, hvad du bør vide om at lære React, og samler det i én omfattende pakke, inklusive videoer, cheatsheets plus særlige bonusser.

Få den insider-information, som hundredvis af udviklere allerede har brugt til at mestre React, finde deres drømmejob og tage kontrol over deres fremtid:


Klik her for at få besked, når det åbner