JavaScript中的稀疏数组与密集数组 2021-11-07 默认分类 暂无评论 1156 次阅读 JavaScript中的数组是相当容易使用的。然而,有一个细微的差别你应该注意:有些数组可能有洞。 在这篇文章中,我将描述`JavaScript`中稀疏数组和密集数组的区别。同时,你会发现创建稀疏数组的常见方法,只是要注意一下。 1. 密集数组 `JavaScript`中的数组是一个代表项目有序集合的对象。 数组中的项目有一个确切的顺序。你可以用一个特殊的数字--索引来访问数组的第n个项目。 const names = ['Batman', 'Joker', 'Bane']; console.log(names[0]); // logs 'Batman' console.log(names[1]); // logs 'Joker' console.log(names[2]); // logs 'Bane' console.log(names.length); // logs 3 `names[0]`访问数组中索引为0的项目(第一个元素)。 数组还有一个属性`length`,它表示数组中的项的数量。在前面的例子中,`names.length`是3,因为数组中的项目数是3。 上面创建的`names`数组是一个密集数组:意思是它包含从0开始直到`names.length-1`的每个索引的项目。 这里有一个函数`isDense(array)`,它决定了数组在每个索引上是否有项目。 function isDense(array) { for (let index = 0; index < array.length; index++) { if (!(index in array)) { return false; } } return true; } const names = ['Batman', 'Joker', 'Bane']; console.log(isDense(names)); // logs true 其中数组中的索引决定了数组在索引位置是否有一个项目。 这里有一个有趣的问题:`JavaScript`中所有的数组都是密集的吗?还是说有些数组的`isDense(array)`会返回错误? 让我们进一步挖掘吧! 2. 稀疏的数组 不幸的是......有些情况下,`JavaScript`的数组会有漏洞。这样的数组被命名为稀疏数组。 例如,如果你使用数组字面,但省略了一个项目,那么就会在缺失的项目的位置上产生一个洞。结果就是创建了一个稀疏数组。 const names = ['Batman', , 'Bane']; console.log(names[0]); // logs 'Batman' console.log(names[1]); // logs undefined console.log(names[2]); // logs 'Bane' console.log(isDense(names)); // logs false `['Batman', , 'Bane']` 数组字头创建一个稀疏数组,在1的索引处有一个洞。如果你访问洞的值--`names[1]`--它被评估为未定义。 要明确地检查在一个特定的索引处是否有一个洞,你需要在`names`表达式中使用索引。 const names = ['Batman', , 'Bane']; // No hole console.log(0 in names); // logs true // Hole console.log(1 in names); // logs false 当然,如果你在一个稀疏数组上运行`isDense()`,它将返回`false`。 const names = ['Batman', , 'Bane']; console.log(isDense(names)); // logs false 现在你对稀疏数组有了一定的了解。但是,创建稀疏数组的常见方法是什么? 让我们在下一节中了解一下。 3. 创建稀疏数组的方法 这里列出了在JavaScript中创建稀疏数组的最常见的方法。 3.1 数组字面 正如已经提到的,在使用数组字面的时候,省略一个值就可以创建一个稀疏数组(注意记录器数组中的空字)。 const names = ['Batman', , 'Bane']; console.log(names); // logs ['Batman', empty, 'Bane'] Array()构造函数 调用`Array(length)`或`new Array(length)`(有一个数字参数)会创建一个完全稀疏的数组。 const array = Array(3); console.log(isDense(array)); // logs false console.log(array); // logs [empty, empty, empty] 3.3 删除操作员 当你在数组上使用`delete array[index]`操作时。 const names = ['Batman', 'Joker', 'Bane']; delete names[1]; console.log(isDense(names)); // logs false console.log(names); // logs ['Batman', empty, 'Bane'] 最初,名字数组是密集的。 但是执行`delete names[1]`会删除索引1处的项目,使名字数组变得稀疏。 3.4 增加长度属性 如果你增加一个数组的长度属性,那么你也会在数组中产生空洞。 const names = ['Batman', 'Joker', 'Bane']; names.length = 5; console.log(isDense(names)); // logs false console.log(names); // logs ['Batman', 'Joker', 'Bane', empty, empty] 最初names数组有3个项目,它是一个密集的数组。 然而,将`names.length`增加到5个项目会产生两个洞--在3和4个索引处。 顺便提一下,减少长度属性并不创造一个稀疏的数组,而是从数组的末端移除项目。 4. 阵列方法和稀疏数组 稀疏数组的一个问题是,许多数组内置方法只是跳过稀疏数组中的洞。 例如,`array.forEach(eachFunc)`并没有不在孔上调用`eachFunc`。 const names = ['Batman', , 'Bane']; names.forEach(name => { console.log(name); }); // logs 'Batman' // logs 'Bane' 和`array.map(mapperFunc)`、`array.filter(predicateFunc)`以及更多的函数做跳过孔。如果你不小心创建了一个稀疏的数组,你可能会发现很难理解为什么一个数组方法不能像预期那样工作。 挑战:你知道`JavaScript`中不跳过空洞的数组函数吗? 5. 总结 在`JavaScript`中,一个数组可以是密集的,也可以是稀疏的。 如果一个数组从0开始直到`array.length - 1`的每个索引上都有项目,那么这个数组就是密集的。否则,如果在任何一个索引上至少缺少一个项目,这个数组就是稀疏的。 虽然你不会经常和稀疏数组打交道,但是你应该知道在哪些情况下会产生稀疏数组。 - 当跳过数组字面内的一个值时 `[1, , 3]` - 当使用`Array(length)`时 - 当使用删除数组`[index]`时 - 当增加`array.length`属性时 稀疏数组的问题是,一些`JavaScript`函数(如`array.forEach()`, `array.map()`等)在迭代数组项目时跳过空洞。 你还知道哪些在`JavaScript`中创建稀疏数组的方法吗? 标签: javascript, 数组
评论已关闭