0

I have a Vue js frontend where I have the following while loop with the following:

while (this.day.getDay() != 0) {
  console.log(this.day)
  this.days.push(this.day)
  this.dates.push(this.day.toDateString())
  this.day.setDate(this.day.getDate() + 1)
}

The loop outputs the following in the console. The output is this

I instantiate the variables as:

day: new Date(Date.now()),
dates: [],
days:[]

I'm wondering why the dates array works correctly and contains sep 6, sep7 and sep 8 but the days array only has sep 09 three times? It is also strange that when I log this.day it logs the correct days but then does not add that to the days array. What is going on here?

Roy Scheffers
  • 3,832
  • 11
  • 31
  • 36
Taylor
  • 1,223
  • 1
  • 15
  • 30
  • 1
    the name `day` is confusing since it is a `Date`, not a day of the date. – lealceldeiro Sep 06 '18 at 20:34
  • 2
    You're pushing a reference to a Date object that you mutate, but the date strings won't change. – Jared Smith Sep 06 '18 at 20:37
  • Probably a dupe of https://stackoverflow.com/questions/1090815/how-to-clone-a-date-object-in-javascript, let someone else agree – epascarello Sep 06 '18 at 20:39
  • 1
    @lealceldeiro I was originally going to do this.day.getDay() to add the day to the array. I decided that adding the date object would be more useful and hadn't got to changing the variable name yet since it wasn't working . I appreciate the concern. – Taylor Sep 06 '18 at 20:52

1 Answers1

2

When you execute this line:

this.days.push(this.day)

You keep pushing the same Date object each time. You never re-assign this.day, you only mutate it with setDate, and every time you do so all the references in that array are updated.

But when you run this line:

this.dates.push(this.day.toDateString())

You are capturing the state at the moment in time you push, strings are immutable.

For a simpler example of what you're getting, look at this

const foo = {bar: 3};
const arr = [foo, foo, foo]; // all the same foo
arr.map(x => x.bar); // 3, 3, 3
foo.bar = 5;
arr.map(x => x.bar); // 5, 5, 5
Jared Smith
  • 19,721
  • 5
  • 45
  • 83
  • Makes perfect sense, I feel dumb for not realizing that. Would the best way to solve the problem be to clone a new Date into the array as shown in @epascarello's link that he posted? – Taylor Sep 06 '18 at 20:50
  • @Taylor yeah, I'd clone it off, or use a different approach altogether (e.g. not OO). – Jared Smith Sep 06 '18 at 23:22