Reputation: 1731
Here is an example that you can type in your console. Super new to Javascript. The example is reproducible by opening a new tab and typing it out in a console (The JSX Fiddle's console feature is in beta, so I'm not sure if it can be trusted)
let clothing = ['card0', 'card1', 'card2', 'card3'];
let timers = {}
let timerObj = {"startTime": null, "pauseTime": null, "elapsedTime": null, "hasSubmitted": false} //Nested object I want for all indices, will manipulate 0th index alone inside for loop
for (var i = 0; i < clothing.length; i++) {
timers[i] = timerObj
if (i == 0) {
timers[i]["startTime"] = Date.now();
}
}
console.log(timers)
What I'm intending to do is, for the 0th index alone, set the timers[0]["startTime"]
as Date.now()
, and for the rest, let the startTime
be null
as defined in the timerObj
.
Strangely, after running the for loop, I see that for all i
, the Date.now()
has been set. I understand that Javascript objects are mutable, but why is why are all indices being set to Date.now()
?
I looked at other Javascript related Object
questions related to a concept call "freezing", not sure I have my basics right.
EDIT: I think this is related the object reference being altered..
Upvotes: 0
Views: 47
Reputation: 2395
Javascript does not copy objects. It passes references around, so when you assign timers[i] = timerObj
once, then you assign Date.now()
once , this value goes to your single timeorObj
. All subsequent assignments of timerObj
to timers[i]
for all i
refer to the single timerObj
you defined.
To fix this force a copy: timers[i] = JSON.parse(JSON.stringify(timerObj));
This will serialize your clean timerObj
to a JSON string, then convert it back to a new javascript object and then assign the new object to timers[i]
.
This way, you end up with copies of timerObj
in each slot of your timers
array.
Upvotes: 1
Reputation: 5308
You have to clone your object
. There are multiple ways to clone. One would be spread operator(...)
. Like below:
let clothing = ['card0', 'card1', 'card2', 'card3'];
let timers = {}
let timerObj = {"startTime": null, "pauseTime": null, "elapsedTime": null, "hasSubmitted": false}
clothing.forEach((val, i)=>{
timers[i] = {...timerObj};
if(i==0){
timers[i].startTime = Date.now()
}
});
console.log(timers);
Upvotes: 1
Reputation: 1361
var clothing = ['card0', 'card1', 'card2', 'card3'];
var timers = {}
var timerObj = {"startTime": null, "pauseTime": null, "elapsedTime": null, "hasSubmitted": false} //Nested object I want for all indices, will manipulate 0th index alone inside for loop
for (var i = 0; i < clothing.length; i++) {
timers[i] = Object.assign({}, timerObj)
if (i == 0) {
timers[i]["startTime"] = Date.now();
}
}
console.log(timers)
You can refer this for more information on this topic.
Upvotes: 1