当数组的某个位置是空元素,即两个逗号之间没有任何值,我们称该数组存在空位(hole)。

    1. var a = [1, , 1];
    2. a.length // 3

    上面代码表明,数组的空位不影响length属性。虽然这个位置没有值,引擎依然认为这个位置是有效的。

    需要注意的是,如果最后一个元素后面有逗号,并不会产生空位。也就是说,有没有这个逗号,结果都是一样的

    1. var a = [1, 2, 3,];
    2. a.length // 3
    3. a // [1, 2, 3]

    上面代码中,数组最后一个成员后面有一个逗号,这不影响length属性的值,与没有这个逗号时效果一样。

    数组的空位是可以读取的,返回undefined

    1. var a = [, , ,];
    2. a[1] // undefined

    使用**delete**命令删除一个数组成员,会形成空位,并且不会影响**length**属性

    1. var a = [1, 2, 3];
    2. delete a[1];
    3. a[1] // undefined
    4. a.length // 3

    image.png

    image.png

    该做法会导致产生稀松数组。

    上面代码用delete命令删除了数组的第二个元素,这个位置就形成了空位,但是对length属性没有影响。也就是说,**length**属性不过滤空位。所以,使用**length**属性进行数组遍历,一定要非常小心

    数组的某个位置是空位,与某个位置是undefined,是不一样的。如果是空位,使用数组的forEach方法、for...in结构、以及Object.keys方法进行遍历,空位都会被跳过。

    1. var a = [, , ,];
    2. a.forEach(function (x, i) {
    3. console.log(i + '. ' + x);
    4. })
    5. // 不产生任何输出
    6. for (var i in a) {
    7. console.log(i);
    8. }
    9. // 不产生任何输出
    10. Object.keys(a)
    11. // []

    如果某个位置是undefined,遍历的时候就不会被跳过。

    1. var a = [undefined, undefined, undefined];
    2. a.forEach(function (x, i) {
    3. console.log(i + '. ' + x);
    4. });
    5. // 0. undefined
    6. // 1. undefined
    7. // 2. undefined
    8. for (var i in a) {
    9. console.log(i);
    10. }
    11. // 0
    12. // 1
    13. // 2
    14. Object.keys(a)
    15. // ['0', '1', '2']

    这就是说,空位就是数组没有这个元素,所以不会被遍历到,而undefined则表示数组有这个元素,值是undefined,所以遍历不会跳过。