Gaurav_soni
Gaurav_soni

Reputation: 6114

Wrong length of array in for loop

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/

Attached screenshot: wrong length

Upvotes: 2

Views: 171

Answers (3)

Supersharp
Supersharp

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

Manoj Shevate
Manoj Shevate

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

Lin Yuan
Lin Yuan

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

Related Questions