Skip to content
Advertisement

Why does a new javascript array have ‘undefined’ entries?

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:

  1. Object is initialized (very bottom)
  2. It calls “load”
  3. When the ajax returns in load, data.objects contains an array of json objects. This array has no undefined entries on it.
  4. setObjects gets called where all the objects from the ajax call are copied to this.objects.
  5. 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 = {};
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement