Reputation: 1329
I have a class which looks similar to what is shown below and it keeps track of imaginary muffins. When the class is instantiated it begins with a blank slate of no muffins.
Of course it would be nothing without the ability to add muffins so that's a feature but there's nothing special about it. It just takes an array of objects and pushes them to this.muffins
.
Also these muffins need to be lent out but not eaten because they are too good looking and are only to be used for decoration. However, when these muffins are lended out, they should be removed from this.muffins
and be kept in their own object under this.lent
so that they cannot be lended out until returned.
The problem is that as I try to remove the muffins from this.muffins
after I add them to this.lent
, it also removes them from this.lent
. I do not know why this happens because I do not understand why they are tied together. I'm confused as to why modifying the muffin array after adding the muffin to this.lent
also affects the muffin in this.lent
.
class Muffins {
constructor() {
this.muffins = [];
}
add(muffins) {
// Add your muffins here.
}
loan(numOfPeople, numOfMuffins) {
const totalMuffinsToLend = numOfPeople * numOfMuffins;
for (let i = 0, person = 0; i < totalMuffinsToLend; ++i, ++person) {
if (person >= numOfPeople) person = 0;
if (!this.lent[person + 1]) this.lent[person + 1] = [];
this.lent[person + 1].push(this.muffins[i]);
this.muffins.filter(muffin => {
if (muffin.id == this.muffins[i].id) this.muffins.splice(this.muffins.indexOf(muffin), 1);
});
}
}
}
For reference, this.muffins
looks similar to:
[
{ id: 1, type: blueberry },
{ id: 2, type: strawberry },
// etc.
]
and this.lent
looks like:
{
'1': { id: 1, type: blueberry },
'2': { id: 2, type: strawberry },
// etc.
}
Upvotes: 0
Views: 63
Reputation: 8930
This refers to my comment on your question. Objects are passed by reference and that's the reason why you see that behavior in your example.
To overcome this, you have to create a copy of your original object (Not passing its reference).
Instead of using JSON.parse(JSON.stringify())
, you could use Object.assign()
as it's a straightforward approach as well as it's better in terms of performance.
You can change your code to something like this:
this.lent[person + 1].push(Object.assign({}, this.muffins[i]));
One thing you need to notice is that Object.assign()
creates a shallow copy (which is enough for your example). But JSON.parse(JSON.stringify())
serializes the whole thing and creates everything from scratch. That's one reason why Object.assign()
is faster.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Hope it helps!!
Upvotes: 0