使用for循环和if语句在嵌套对象中设置键的值发生错误

这是您可以在控制台中键入的示例。 Java语言的超级新手。通过打开一个新标签页并在控制台中键入该示例,可以复制该示例(JSX Fiddle的控制台功能处于beta版,因此不确定是否可以信任)。

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.

编辑:我认为这与被更改的对象引用有关。

评论
亦莫离
亦莫离

You have to clone your object.

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);
点赞
评论
mneque
mneque

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.

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.

点赞
评论
cvitae
cvitae
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.

点赞
评论