# 什么是数组空位
形象地说,公交车上,无人坐的位置,就是空位(子)
相反,只要被占用就不是空位,无论是坐人了,还是放了私人物品
而数组的空位与之类似
当数组下标索引位无任何值时索引位就是空位
值得注意的是,虽然索引位无任何值
但通过下标访问时值为 undefined
就像访问对象上不存在的属性一样
创建空位数组有几种方式:
// 字面量
let arr = [, , ,]
// 构造函数
let arr = new Array(3)
// length
let arr = []
arr.length = 3
2
3
4
5
6
7
8
9
值得注意的是数组空位访问虽然值是 undefined
但与直接使用 undefined 初始化数组完全是两回事
// 使用 undefined 初始化数组
let arr = [undefined, undefined, undefined]
2
很显然,数组的索引位有值了,虽然值为令人迷惑的 undefined
此时就不是空位数组了
数组的空位在浏览器控制台与 Nodejs 表现类似
// 浏览器控制台
Array(3) // (3) [empty × 3]
// Nodejs
Array(3) // [ <3 empty items> ]
2
3
4
5
# 数组空位检测
空位虽然上面没有任何值,但依然占据长度 length
比如下面数组长度是 4,不是 3
let arr = [1, , 2, 3] // length 4
如何检测数组中空位?
使用 in 操作符或 hasOwnProperty 方法
1 in arr // false,数组索引 1 是空位 - 不推荐
// hasOwnProperty 与 in 类似
arr.hasOwnProperty(1) // false
2
3
4
上述方法不够灵活,因为空位索引是任意的
map + includes 方法
arr.map(v => arr.includes(v)).includes() // true, 数组包含空位,注意 includes 不传任何参数 - 推荐
原理:map 对于数组空位,跳过不处理,但在结果中保留
includes 方法把空位当成 undefined 处理
includes 不传参数时,参数默认为 undefined
includes() 与 includes(undefined) 等价
一些教程上说,includes 第一个参数必须,测试得知,此说法是错的
另外
试图通过数组索引或 at 方法获取空位值是获取不到的,空位上本就无值 所以结果默认都是 undefined
# 不了解数组空位产生的 bug
在此之前我是不知道的,需求是原动力
先看下祖传的源代码
创建 7 项二维数组
let dataArr = Array(7).map(() => [])
我以为结果是 [[], [], [], [], [], [], []]
但实际结果 [empty × 7]
一脸懵逼 ...
但看到 empty
勾起曾经看过关于数组空位
的文档使用说明
这该死的记忆
map 遍历成员,空位不处理,直接跳过,而且不会进行回调处理,但在结果中会保留
意思就是上面的 map 方法的回调根本就没有执行
因为成员全是空位
所以返回一个全是空位的新数组
测试下:
let dataArr = Array(7).map(() => console.log(1))
正常 map 回调执行应该打印 7 次 1
结果是没有一次打印
数组对于空位处理方式除了上述的方式外
还有当成 undefined 处理
或者跳过并在结果中忽略
# 数组空位处理大全
数组方法对于空位处理有 3 种方式:
跳过,不处理:表示如果磁到索引位是空位时,不会进入回调函数,直接跳过
1. 跳过,不处理,结果中原样保留空位
- map
- toString
- toLocaleString
- concat
- copyWithin
- push
- pop
- reversse
- unshift
- shift
- slice
- splice
- sort
列举两个比较特殊的:
let arr = [10, , 3]
// [10, , 3]
arr.map(v => {
console.log(v) // 只打印 10, 3,空位由于跳示,不处理,所以不打印
return v
}) [
// [10, 3, ,],空位始终位于最后
arr.sort()
2
3
4
5
6
7
8
9
10
2. 跳过,不处理,结果中不保留空位(当数组不存在空位处理)
- indexOf
- lastIndexOf
- forEach
- filter
- flat
- flatMap
- every
- some
- reduce
- reduceRight
// [10, 3]
arr.flat()
// true
arr.every(v => v)
// false
arr.some(v => !v)
// 13
arr.reduce((acc, cur) => acc + cur)
2
3
4
5
6
7
8
9
10
11
3. 转成 undefined 或当正常元素处理
- find
- findIndex
- includes
- join
- entries
- values
- Array.from
- [...arr]
- fill: 当正常元素处理
// [2, 2, 2]
arr.fill(2)
// [10, undefined, 3]
Array.from(arr)
// [10, undefined, 3]
console.log([...arr])
2
3
4
5
6
7
8
上图比逼逼更直接:
# 小结
知晓什么是数组空位
产生的方式及检测方法
以及在数组方法中的具体表现
避免踩坑
于实际开发中数组空位出现概率比较小
没有谁想着要创建空位数组
于特定需求中注意即可
# 一些想法
数组空位的产生,增加了心智负担
需要比细节更细 ...
但想想,为什么会出现数组空位
这个东西
产生它的需求是什么?
大胆猜想下,可能是因为 Array(n)
的怪异行为
把传入的数字 n
理解为要创建长度为多少的数组
于是,多出来的索引位,用什么填充合适呢?
使用 undefined、null
等基本类型值?
或者发明新的占位符之类的?(这又要增加学习负担了)
无论哪种都不太合适
于是保持原状,既然没有任何值,没有就好了,何必自寻烦恼
另外一种猜想
产品需求导致的语法不得不如此设计,哈哈哈哈...
# 参考
扫一扫,微信中打开