当数组的某个位置是空元素,即两个逗号之间没有任何值,我们称该数组存在空位(hole)。
var a = [1, , 1];a.length // 3
上面代码表明,数组的空位不影响length属性。虽然这个位置没有值,引擎依然认为这个位置是有效的。
需要注意的是,如果最后一个元素后面有逗号,并不会产生空位。也就是说,有没有这个逗号,结果都是一样的。
var a = [1, 2, 3,];a.length // 3a // [1, 2, 3]
上面代码中,数组最后一个成员后面有一个逗号,这不影响length属性的值,与没有这个逗号时效果一样。
数组的空位是可以读取的,返回undefined。
var a = [, , ,];a[1] // undefined
使用**delete**命令删除一个数组成员,会形成空位,并且不会影响**length**属性。
var a = [1, 2, 3];delete a[1];a[1] // undefineda.length // 3


该做法会导致产生稀松数组。
上面代码用delete命令删除了数组的第二个元素,这个位置就形成了空位,但是对length属性没有影响。也就是说,**length**属性不过滤空位。所以,使用**length**属性进行数组遍历,一定要非常小心。
数组的某个位置是空位,与某个位置是undefined,是不一样的。如果是空位,使用数组的forEach方法、for...in结构、以及Object.keys方法进行遍历,空位都会被跳过。
var a = [, , ,];a.forEach(function (x, i) {console.log(i + '. ' + x);})// 不产生任何输出for (var i in a) {console.log(i);}// 不产生任何输出Object.keys(a)// []
如果某个位置是undefined,遍历的时候就不会被跳过。
var a = [undefined, undefined, undefined];a.forEach(function (x, i) {console.log(i + '. ' + x);});// 0. undefined// 1. undefined// 2. undefinedfor (var i in a) {console.log(i);}// 0// 1// 2Object.keys(a)// ['0', '1', '2']
这就是说,空位就是数组没有这个元素,所以不会被遍历到,而undefined则表示数组有这个元素,值是undefined,所以遍历不会跳过。
