为什么新的javascript数组有';未定义';条目?

为什么新的javascript数组有';未定义';条目?,javascript,undefined,Javascript,Undefined,下面是一个示例,它演示了一个数组,当您填充它时,它也会获取其中所有类型的未定义项 这是在Firefox19.0/firebug上发生的,不确定是否发生在其他浏览器上 基本流程: 对象已初始化(最底部) 它称为“加载” 当ajax加载返回时,data.objects包含一个json对象数组。此数组上没有未定义的项 调用setObjects时,ajax调用中的所有对象都复制到this.objects 当它们被复制时,我可以看到未定义的条目出现在firebug中,如果我没有第二次传递数组并拼接出未定义

下面是一个示例,它演示了一个数组,当您填充它时,它也会获取其中所有类型的未定义项

这是在Firefox19.0/firebug上发生的,不确定是否发生在其他浏览器上

基本流程:

  • 对象已初始化(最底部)
  • 它称为“加载”
  • 当ajax加载返回时,data.objects包含一个json对象数组。此数组上没有未定义的项
  • 调用setObjects时,ajax调用中的所有对象都复制到this.objects
  • 当它们被复制时,我可以看到未定义的条目出现在firebug中,如果我没有第二次传递数组并拼接出未定义的条目,那么在尝试访问模板中的数组元素时,它会打断小胡子
  • 为什么javascript会自动用未定义的条目填充this.objects数组

    代码如下:

    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( );
    
    函数MailerFromProfile()
    {
    //特权的
    this.objects=[];
    这个参数是load();
    }
    MailerFromProfile.prototype.setObjects=函数(对象)
    {
    for(对象中的变量i)
    {
    if('undefined'!==对象[i])
    {
    this.objects[objects[i].id]=objects[i];
    }
    }
    //我不应该这样做:
    for(var i=0;i
    当您执行此操作时

    this.objects[ objects[ i ].id ] = objects[ i ];
    
    您要求数组将
    this.objects
    扩展到
    objects[i].id
    。当您需要未填充索引处的元素时,引擎没有其他解决方案,只能为您提供
    未定义的

    如果数组大部分是空的(稀疏数组),则可能应该使用对象作为贴图,即使用

    this.objects = {};
    
    为什么javascript会自动用未定义的条目填充this.objects数组

    它没有,但它可以看起来像那样

    关键点是您正在设置如下数组项:

    this.objects[ objects[ i ].id ] = objects[ i ];
    
    …显然,
    对象[i].id
    有时高于数组中的条目数

    标准JavaScript数组(除非由JavaScript引擎优化),它是一个对一些事情进行特殊处理的对象

    让我们举一个简单的例子:

    var a = [];            // An empty array
    console.log(a.length); // 0
    a[3] = "foo";          // Puts an entry at index 3
    console.log(a.length); // 4
    
    如您所见,如果写入的数组项超出了数组的末尾,则数组的
    长度将调整为比写入的索引高一个

    但是JavaScript不会用
    未定义的
    来“填充”数组。
    a[0]
    a[1]
    a[2]
    处的条目不存在

    console.log(1 in a);   // false
    
    但是,如果您向数组请求一个不存在的条目,则会得到
    未定义的

    console.log(a[1]);     // undefined
    
    …就像您在请求不存在的属性时从任何其他JavaScript对象执行的操作一样(因为数组“元素”实际上是对象属性,而数组“索引”实际上是属性名称)

    这与实际存在的值为
    未定义的条目不同,也可能是:

    a[1] = undefined;
    console.log(1 in a);   // true
    console.log(a[1]);     // undefined
    
    因此,Mustach在数组中从
    0
    循环到
    length-1
    ,并要求输入一些不存在的条目,导致
    未定义

    这是一个很长的说法,您可能希望将该行更改为:

    this.objects.push(objects[ i ]);
    

    但是JavaScript不会用未定义的字符“填充”数组。[0]、[1]和[2]上的条目不存在:
    实际上存在,您可以看到监视列表中所有未定义的条目。@DevNull:不存在。我建议重新阅读上述内容(我会给出示例),和/或阅读。