Here’s a sample that demonstrates an array that as you fill it in, it gets all types of undefined entries in it as well.
This is on firefox 19.0/firebug, not sure if it happens on other browsers.
Basic flow:
- Object is initialized (very bottom)
- It calls “load”
- When the ajax returns in load, data.objects contains an array of json objects. This array has no undefined entries on it.
- setObjects gets called where all the objects from the ajax call are copied to this.objects.
- As they are copied I can see undefined entries show up in firebug, If I didn’t pass the array a second time and splice out the undefined entries it breaks mustache when trying to access the elements of the array in a template.
Why does javascript automatically pad out the this.objects array with undefined entries?
Here’s the code:
function MailerFromProfile( ) { // privileged this.objects = []; this.load( ); } MailerFromProfile.prototype.setObjects = function( objects ) { for( var i in objects ) { if( 'undefined' !== objects[ i ] ) { this.objects[ objects[ i ].id ] = objects[ i ]; } } // I should not have to do this: for( var i = 0; i < this.objects.length; i++ ) { if( typeof this.objects[ i ] === 'undefined' ) { this.objects.splice( i, 1 ); i--; } } } MailerFromProfile.prototype.setTemplate = function( n, v ) { this.template[ n ] = v; } MailerFromProfile.prototype.load = function( ) { jQuery.post( MAILER_PATH, { session: MAILER_SESSION, object : 'from_profile', action : 'list' }, function( data ) { if( typeof data.objects !== 'undefined' ) { g_mailer_from_profiles.setObjects( data.objects ); } }, 'json' ); } var g_mailer_from_profiles = new MailerFromProfile( );
Advertisement
Answer
When you do this
this.objects[ objects[ i ].id ] = objects[ i ];
you ask for the array to extend this.objects
up to objects[ i ].id
. There is no other solution for the engine than to give you undefined
when you require the element at an unfilled index.
If your array is mostly empty (a sparse array), you should probably use an object as map instead, that is initialize it with
this.objects = {};