Reputation: 6114
i am facing a strange behaviour in a for loop that contains array of objects
The following is the example
var store = {};
var storesWithTimestamps = [];
for (var i=0;i<2;i++){
console.log("inital list",storesWithTimestamps); //1
console.log("inital length",storesWithTimestamps.length); //2
store = {};
store.latestTimestamp = null;
store.storeName = "testStore";
storesWithTimestamps.push(store);
console.log("new list",storesWithTimestamps); //3
console.log('new length',storesWithTimestamps.length); //4
}
The problem is log statement 3 shows a array of object with 2 items in the 1st iteration , but the log statement 4 shows the length as 1.
The output of the log statement 3 is the same for both the iteration like this, [{latestTimestamp:null,storeName:"testStore"},{latestTimestamp:null,storeName:"testStore"}]
Where as it should be 1st loop:
[{latestTimestamp:null,storeName:"testStore"}]
2nd loop:
[{latestTimestamp:null,storeName:"testStore"},{latestTimestamp:null,storeName:"testStore"}]
FYI: this works as expected in Safari but not on chrome - OSX Attached fiddle: http://jsfiddle.net/gauravsoni/09Ls3rtx/
Upvotes: 2
Views: 171
Reputation: 31161
Actually it's due to the Debugger behavior.
If the debugger is opened when you run the script, the output in the console will be correct.
If the debugger is not opened when you run the script, the object is evaluated at the time the console is displayed. That's why you can see 2 objects in the array.
I think it is what @yorlin was meaning.
Addendum:
You may want to use the JSON.stringify()
method to log the instant object properties:
console.log( "inital list:", JSON.stringify( storesWithTimestamps ) ) //1
...
console.log( "new list:", JSON.stringify( storesWithTimestamps ) ) //3
Nota bene: In the console, italic values were evaluated instantly, while non-italic values are evaluated when they are displayed (as you can see in the blue [ i ] next to the values).
Conclusion: In the second posted screenshot we can see clearly it was not a Chrome bug.
Upvotes: 2
Reputation: 742
This is happening due to async nature of console.log() you can find more details regarding this behavior at console.log() async or sync?
you can try workaround to log the proper value as below -
var store = {};
var storesWithTimestamps = [];
for (var i=0;i<2;i++){
console.log("inital list",storesWithTimestamps); //1
console.log("inital length",storesWithTimestamps.length); //2
store = {};
store.latestTimestamp = null;
store.storeName = "testStore";
storesWithTimestamps.push(store);
console.log("new list",JSON.stringify(storesWithTimestamps)); //3 instead of passing object, pass serialized snapshot of the object
console.log('new length',storesWithTimestamps.length); //4
}
Upvotes: 1
Reputation: 538
I've tried this....Just like @yorlin and @Supersharp said.
You can check it in console more clear.
var store = {};
var storesWithTimestamps = [];
//Checkout the status of ary
function displayObj(objAry){
var info="\n";
for(var i=0;i<objAry.length;i++){
var data=objAry[i];
info+='\t\trecord('+i+').id:'+data.id+'\n';
}
return info;
}
for (var i=0;i<2;i++){
console.log("inital list",storesWithTimestamps); //1
console.log("inital length",storesWithTimestamps.length); //2
//put an id to identify
store = {id:i};
store.latestTimestamp = null;
store.storeName = "testStore";
storesWithTimestamps.push(store);
console.log("new list",displayObj(storesWithTimestamps)); //3
console.log('new length',storesWithTimestamps.length); //4
}
Upvotes: 1