1

(I was a little uncertain how to word my question.) I've just started learning JavaScript after studying other languages, and already I'm a little confused about its behavior. I wrote this code:

var todoList={
  todo:[],
  display:function(){
    console.log(this.todo);
  },
  addItem:function(itemText){
    this.todo.push({text:itemText,completed:false});
    this.display();
  },
  changeItem:function(index,newText) {
    this.todo[index].text=newText;
    this.display();
  }
};


todoList.addItem('item 1');
todoList.addItem('item 2');
todoList.changeItem(0, 'new item 1');

and when I run it, I expect to see in the console three arrays (which I do), because of the console.log() statements. I expect to see displayed

  • an array with 1 item ('item 1') after todoList.addItem('item 1') is run, then
  • an array with 2 items ('item 1', 'item 2') after todoList.addItem('item 2') is run, and
  • an altered array with 2 items ('new item 1', 'item 2')aftertodoList.changeItem(0, 'new item 1')`.

Instead, however, I see displayed 3 arrays but each one has the same items ('new item 1','item 2'). It's as if all the code is run before anything is console.logged.

What am I missing?

Al C
  • 5,175
  • 6
  • 44
  • 74
  • I suspect your seeing an artifact of your browser debugger. With a tweak to the display function to have it render just the text property of each array element it outputs exactly what you expect. The debugger is probably live evaluating the array so your seeing the current value per `log` call. At least that's what I was seeing in chrome. – asawyer Sep 23 '20 at 18:06
  • On which platform did you run this code? I just tried running this on chrome's developer console and it works just as expected. – Prajwal Kulkarni Sep 23 '20 at 18:07
  • @PrajwalKulkarni I ran the code in Firefox's developer console, Windows 10 – Al C Sep 23 '20 at 18:13
  • @asawyer Yes, I tweaked to display just the text property, and it does output what I expect. – Al C Sep 23 '20 at 18:20

2 Answers2

2

Your code works correctly, but I presume you are running it in a browser, and when you click on the object in the console output, it reevaluates its value.

Try printing its length instead. You will see, that first you have 1 item, and the 2 items for the second and third time. You could also go through the items with a foreach for example, and print its values like that.

botiapa
  • 353
  • 2
  • 13
  • Pedantic note - the third call mutates an array item instance, it does not add a third item to the array. – asawyer Sep 23 '20 at 18:09
1

I think this should fix your problem by printing the actual item each time instead of the entire array:

var todoList={
  todo:[],
  display:function(){
    for (var i = 0; i < this.todo.length; i++) {
      console.log(todoList.todo[i]);
    }
    console.log("End of results");
  },
  addItem:function(itemText){
    this.todo.push({text:itemText,completed:false});
    this.display();
  },
  changeItem:function(index,newText) {
    this.todo[index].text=newText;
    this.display();
  }
};

todoList.addItem('item 1');
todoList.addItem('item 2');
todoList.changeItem(0, 'new item 1');
ajarrow
  • 414
  • 2
  • 10
  • This response, coupled with the info at https://stackoverflow.com/questions/11284663/console-log-shows-the-changed-value-of-a-variable-before-the-value-actually-ch?noredirect=1&lq=1 answers my question. – Al C Sep 23 '20 at 18:42