Destructuring, Spread, and Rest
Pulling values out of objects and arrays, and copying them without mutation.
A show object holds fields you read over and over. Destructuring gives each field its own name, and three dots copy the rest.
Destructuring objects
Destructuring unpacks fields into variables in one step. The name on the left has to match the field name.
seasons is not in the object, so the default 1 is used. network prints
null, not "Unknown". A default only fills in undefined.
Destructuring in parameters
You can unpack a parameter in the function's own brackets. React components read their props this way.
The first call prints label: Severance (2022). The second throws a
TypeError, because you cannot read title off undefined. Writing
function label({ title, year } = {}) gives it an empty object to unpack.
Destructuring arrays
Arrays unpack by position. You choose the names, so a name never picks the item you meant.
The last line prints named andor: Severance. Position one is Severance,
whatever you call it.
Rest and spread
Both are three dots. Rest collects leftovers on the left of an =. Spread
expands a value on the right.
Rest collects
Functions and Parameters used ...rest to collect extra
arguments. The same dots work in a pattern.
rest is a new object with the fields you did not name.
Spread expands
Spread copies every field into a new object. A field written after the spread replaces the copied one.
seen.watched is true and the original is untouched. wrong.watched is
false, because ...show ran after it and put the old value back.
Arrays spread the same way.
shows still has two items. added is a new array with three.
Copying instead of mutating
An object variable holds a reference, not the object itself. Two names can point at one object, so changing it through either name changes it for both.
show.year is now 2020, even though you only wrote to alias. other.year
is still 2022, because copy is a different object.
This matters later. React works out what changed by comparing objects, so it misses a change you make in place.
One level deep
Spread copies the top level only. A nested object is copied as a reference, so both copies still share it.
Writing to shallow.rating changed show.rating too: both print 1. deep
kept its own rating, so it prints 9. Copy at every level you change.
Common mistakes
- Expecting a default to fill in
null. A default only replacesundefined. - Spreading last.
{ watched: true, ...show }puts the old value back; spread first, then override. - Trusting a shallow copy.
{ ...show }shares every nested object.
Exercise
addGenre should return a new show with the genre added, and leave the show
it was given alone. Right now both lines print the same list.
The output should read:
original: Drama
updated: Drama,Thriller
Hint: spread the show into a new object, and the old genres into a new array.