编写前端测试过程中经常会有这样的需求,快速生成一个数组。或则说生成一个随机长度的数组.
一般会想到用for 循环。
function(){
let hours = [];
for(let k = 0; k < 24; k++ )hours.push(k);
return hours;
}
这样的话,肯定不能满足随手生成一个数组的要求。我想要的是更可读,很快速的方法:
Array(24).map((v, index) => index);
然后我们可能会这样做,但是并没有达到我们的效果,回调函数没有被执行,检查 Array(24)的长度,确实有24。
这是由于js里面的稀疏数组逻辑造成的,简单的说就是Array(24)初始化了一个24长度的数组,生成了索引,但并没有分配空间,Array的迭代器,会直接忽略掉没有初始化的元素。
// 测试一下
const aa = Array(23);
aa.forEach((v) => {console.log(v);}) // 没有执行
aa[3] = 9;
aa.forEach((v) => {console.log(v);}) // 一次执行 9
const bb = Array.apply(null, Array(24)).map((_, h) => h);
// 成功, apply有展开数组参数的作用,由此可见展开逻辑不是用的迭代器,多半用的for
const bb = Array.call(null, ...Array(24)).map((_, h) => h);
// 成功
个人想法: 展开参数需要保证参数个数和顺序的特殊性,所以不能用Array自带的迭代器来实现,需要用传统的for循环实现。
Array(24).fill(null).map((_, h) => h);
## 关于随机长度数组就比较简单了
Array(Math.ceil(Math.random() * 100)).fill(null).map((_, h) => h);
Array.from函数的实现方式就更有意思了。我没法看到from函数的实现,但是可以猜测一下.
const bb = Array.from({length: 24}).map((v, k) => k);
// 可行
const bb = Array.from(Array(24)).map((v, k) => k);
// 可行
const bb = Array.from([1,2,undefined,undefined]).map((v, k) => k);
// 可行
from函数是把类似数组或则包含迭代器方法的对象转换成Array. 最简单的类似数组,就是一个包含了length属性的对象了。如果我们真的传一个数组,也行。看起来针对数组是没有使用迭代器方法的。