开发过程中遇到了一个问题,需要mock一些数据。一开始直接用的静态常量,后来想想这实在是太占地方了,尤其为了符合eslint需要写很多行,找其它部分代码的时候也不方便,而且很显然,我们可以用“时间换取空间”,通过程序简化这一部分。
我需要mock的是一个数组,数组里有一些固定的或是随机的数据(这里不妨假设只需要填满不同的数字),那么如何才能简便的mock一个这样的数组呢?

如何初始化一个从0到99的数组

通常最简单的能想到的方法,不就是个循环嘛

1
2
3
4
let result = [];
for (let i = 0; i < 100 ; i++) {
result.push(i);
}

但这实在是太笨了,“高级程序员是不会使用for循环的(偷笑)”,在js中,我们可以用其它的方法循环。比如 map。 利用 map 方法会看起来更简便些,但我们首先要构造一个长度为100并且初始化了的数组。

如何构造一个长度为100的数组

  1. Array的构造函数 + …扩展运算符

通过 Array 的构造函数 Array(100) 我们可以创建长度为100的数组,但是并没有初始化。

我们可以通过…来初始化它

1
[...Array(100)];
  1. 将类数组对象初始化为数组 - Array.from

类数组对象比较好写 {length: 100} ,那如何把它变成初始化了的数组呢?

可以直接用 Array.from ,这个方法本身就是为了从一个类似数组或可迭代对象创建一个新的数组。

1
Array.from({length: 100});
  1. 将类数组对象初始化为数组 - Array.apply

使用 Array({length: 100}) 并不会创建长度为100的数组,这是因为 Array 的构造函数把入参当成了一个对象进行了初始化,如何让Array的构造函数把入参作为类数组对象呢?可以使用 apply

1
Array.apply(null, {length: 100});
  1. Array.prototype.slice + …扩展运算符

Array 的 slice 方法可以对数组进行拷贝,也可以用它来将类数组对象拷贝成长度为100的数组,直接使用是不行的,因为毕竟类数组对象还不是数组,我们可以用 call 或者 applybind 来调用它

1
2
3
[...Array.prototype.slice.call({length: 100})];
[...Array.prototype.slice.apply({length: 100})];
[...Array.prototype.slice.bind({length: 100})()];

利用 Array.prototype.map 初始化

有了已经初始化为undefined的数组后面就是将数组填满值了

1
2
3
4
[...Array(100)].map((_, i) => i);
Array.from({length: 100}, (_, i) => i);
Array.apply(null, {length: 100}).map((_, i) => i);
// 上面4的写法已经够长了,我就不加map了

因为 mapFn 可以随意写,我们还可以用以上两种方法构造诸如全是1的数组

利用 Object.keys() 获取初始化数组的key

注意,我们要初始化的值其实和数组的key是相同的!这样我们其实可以有一些取巧的方法,比如,可以通过 Object.keys() 来得到这样一个符合条件的新的数组。Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。

1
2
3
Object.keys([...Array(100)]);
Object.keys(Array.from({length: 100}));
Object.keys(Array.apply(null,{length:100}));

利用 Array.prototype.keys 生成迭代器

如果我们构造了一个长度为100的数组但是没有初始化,我们可以生成从0到99的数组吗?其实也是可以的,我们可以通过 Array.prototype.keys 生成一个数组迭代器对象,然后再通过 …扩展运算符 来生成一个从0到99的数组

1
2
[...Array(100).keys()]
[...Array.prototype.slice.call({length: 100}).keys()]