代码之家  ›  专栏  ›  技术社区  ›  Marcus Junius Brutus

阵列中的孔与未定义的孔以及map函数

  •  5
  • Marcus Junius Brutus  · 技术社区  · 10 年前

    我明白 map is not called on undefined indexes 对于数组,我理解未定义的索引与显式分配了“undefined”值的数组索引不同(是的,不是吗?)。然而,如何区分阵列中的孔和 undefined 价值观

    以下代码:

    foo.js

    var arr = [,,undefined,,,,3,,,4];
    console.log("A hole the same as undefined? "+(arr[0]===undefined?"yes":"no"));
    var _ignored = arr.map(function(x) {console.log("f called on ["+x+"]");});  
    

    …运行时产生:

    $ node foo.js 
    A hole the same as undefined? yes
    f called on [undefined]
    f called on [3]
    f called on [4]
    

    …更换时也会有类似的结果 地图 具有 forEach .

    2 回复  |  直到 10 年前
        1
  •  7
  •   georg    10 年前

    这个 in 运算符告诉您是否已将索引实际分配给:

    a = []
    a[5] = window.foo
    
    document.write(a[4] + "<br>")
    document.write(a[5] + "<br>")
    
    document.write((4 in a) + "<br>")
    document.write((5 in a) + "<br>")

    Javascript数组实际上是具有特殊 length 属性和数组索引只是属性名称(实际上,它们内部是偶数字符串,而不是数字)。因此,上述定义等同于:

    a = {
      5: window.foo,
      length: 6
    }
    

    因此,所有与键相关的对象功能(如 在里面 , hasOwnProperty , Object.keys )也适用于数组索引。

    forEach 和其他迭代方法 work by iterating from 0 to length-1 and checking if n-th index is actually present in the argument ,他们不“知道”参数实际上是一个数组还是一个泛型对象:

    a = {1:'one', 5:'five', length:100};
    
    [].forEach.call(a, function(x) {
      document.write(x)
    });
        2
  •  -2
  •   Xavier Gomez    10 年前

    你所说的“洞”并不完全是一个洞:

    var a = [,,,,,,,,,,];
    a.length;  // 10
    var n, k;
    n=0; for (k in a){if (a.hasOwnProperty(k)){++n;}else{break;}};
    n; // 10 : a has 10 own properties, all SET to undefined
    

    现在删除所有属性,并重新计数

    while (n--) delete a[n];
    for (k in a){if (a.hasOwnProperty(k)){++n;}else{break;}};
    n; // 0
    a.length; // 10 : a is identical to Array(10), empty array of length 10
    

    要获得带有孔的数组,您可以手动删除属性,或者从array(N)开始并用值填充一些索引,或者使用push/splice而不是返回数组的方法。例如:

    Array(2).concat([void(0)]).concat(Array(3)).concat([3]).concat(Array(2)).concat([4]);
    

    尽管第一个被加数(数组(2))没有,但它完全复制原始数组(它有长度10和10个自己的属性)。


    编辑 :以上内容在ExtendeScript中进行了测试,但在最近的浏览器中不适用(请参见注释)。随后在Firefox中测试,[,,,,]确实没有自己的属性。。。