admin管理员组文章数量:1400201
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( );
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( );
Share
Improve this question
asked Feb 28, 2013 at 8:19
Dev NullDev Null
8281 gold badge9 silver badges20 bronze badges
2 Answers
Reset to default 6Why does javascript automatically pad out the this.objects array with undefined entries?
It doesn't, but it can look that way. :-)
The key bit is that you're setting array entries like this:
this.objects[ objects[ i ].id ] = objects[ i ];
...and so apparently, objects[ i ].id
is sometimes higher than the number of entries in the array.
The standard JavaScript array isn't really an array at all (unless optimized by the JavaScript engine),¹ it's an object with special handling of a couple of things.
Let's take a simpler example:
var a = []; // An empty array
console.log(a.length); // 0
a[3] = "foo"; // Puts an entry at index 3
console.log(a.length); // 4
As you can see, if you write to an array entry that's beyond the end of the array, the length
of the array is adjusted to be one higher than the index you wrote to.
But JavaScript doesn't "pad out" the array with undefined
; the array is sparse. The entries at a[0]
, a[1]
, and a[2]
don't exist:
console.log(1 in a); // false
But if you ask an array for an entry that doesn't exist, you get undefined
:
console.log(a[1]); // undefined
...just like you do from any other JavaScript object when you ask for a property that doesn't exist (because array "elements" are actually object properties, and array "indexes" are actually property names).
That's different from an entry actually existing there with the value undefined
, which is also possible:
a[1] = undefined;
console.log(1 in a); // true
console.log(a[1]); // undefined
So Mustache is looping through the array from 0
to length - 1
and asking for the entries, some of which don't exist, resulting in undefined
.
Here's a runnable version of the various code snippets above:
var a = []; // An empty array
console.log(a.length); // 0
a[3] = "foo"; // Puts an entry at index 3
console.log(a.length); // 4
console.log(1 in a); // false
console.log(a[1]); // undefined
a[1] = undefined;
console.log(1 in a); // true
console.log(a[1]); // undefined
Which is a long way of saying, you may want to change that line to:
this.objects.push(objects[ i ]);
¹ That's a post on my anemic old blog.
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 = {};
本文标签: Why does a new javascript array have 39undefined39 entriesStack Overflow
版权声明:本文标题:Why does a new javascript array have 'undefined' entries? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744221561a2595888.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论