Moxie and Gus start out with the same number of toys. But then Gus starts stealing from Moxie (he’s cute but a bit of a toy hog). Unfortunately, this code doesn’t keep track of the toy counts as expected. What’s the issue?
Code with error
Corrected code
Explanation
You may have heard of mutability before. Objects and arrays in JavaScript are mutable, which means a couple things things:
- Their properties can be updated even if they’ve been declared as a
const
- They represent a chunk of memory, not an actual value.
Let’s tackle the second item: an object variable represents a memory location instead of an actual value. As an analogy, think of the object variable gusFeathers
as a pointer to a bag of feathers (owned by Gus). If you assign another object variable to equal gusFeathers
(const moxieFeathers = gusFeathers
), this is not going to make a new bag of feathers. Instead, both gusFeathers
and moxieFeathers
lead you to the exact same bag.
So if someone takes a feather from gusFeathers
, then moxieFeathers
loses a feather too. They’re the same thing.
If you want to make a new bag of feathers, there are several ways to go about it. You could use the spread operator , Object.assign()
, or Object.create()
. Any of these make a copy of the object, with its own memory location. So const moxieFeathers = {...gusFeathers}
results in two independent objects. In the “bag of feathers” analogy, someone could set fire to gusFeathers
(I suspect Moxie), and moxieFeathers
will remain intact.
This “pointer to a memory location” concept is also why properties can be updated, even if a mutable object is a const
. When you update a property, you’re not updating the pointer to the location in memory. You’re updating what’s stored at that location. So this is fine:
but this will throw an error:
Further Reading
- MDN on shallow copies vs deep copies