今天在学习vue时,在文档的一个例子中发现一个代码片断javascript
Array.apply(null, { length: 20 }).map(function () {
return createElement('p', 'hi')
})
// 目的是为了建立一个20次的循环
复制代码
这让我想起来以前在学习中写demo时,想要用forEach来作一个若干次的循环(以为写for循环麻烦),当时是这样写的vue
Array(10).forEach(function(){
// do something
})
复制代码
结果是并不会进入循环,后来查询mdn缘由以下:java
forEach 方法按升序为数组中含有效值的每一项执行一次callback 函数,那些已删除(使用delete方法等状况)或者未初始化的项将>>被跳过(但不包括那些值为 undefined 的项)(例如在稀疏数组上)。es6
划重点: 未初始化的项将被跳过
api
原来由于经过 Array(10) 或者 new Array(10) 方式建立的数组是一个有length属性的空数组,其中的每一个元素尚未被赋值(初始化),因此会变forEach map 等方法跳过数组
Array(10) // [empty × 10] length: 10
new Array(10) // [empty × 10] length: 10
复制代码
可是经过今天看到的这个方法就能够建立一个能够被forEach等方法遍历的数组,这是为何呢?app
// 这三个方法返回的是一个长度为10的数组,且每个元素都被赋值成undefined
Array.apply(null, {length: 10})
Array.apply(null, Array(10))
Array.apply(null, new Array(10))
// [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]
复制代码
这里先复习一下Array构造函数的用法,下面是mdn的引用函数
Array 构造器会根据给定的元素建立一个 JavaScript 数组, 可是当仅有一个参数且为数字时除外: 一个范围在 0 到 232-1 之间的整数, 此时将返回一个 length 的值等于 arrayLength 的数组对象(言外之意就是该数组此时并无包含任何实际的元素, 不能理所固然地认为它包含 arrayLength 个值为 undefined 的元素)。 注意,后面这种状况仅适用于用 Array 构造器建立数组,而不适用于用方括号建立的数组字面量。学习
划重点 可是当仅有一个参数且为数字时,组此时并无包含任何实际的元素,不能理所固然地认为它包含 arrayLength 个值为 undefined 的元素
就是说建立出来的数组中的元素并无被赋值(初始化)
ui
而后再复习一下Array.apply方法的使用
Array.apply() 方法接收两个参数, 第一个为调用时指定的上下文(context); 第二个为一个数组或者一个类数组对象;
Array.apply(null, {length: 10})
Array.apply(null, Array(10))
Array.apply(null, new Array(10))
// 这三个方法至关于
Array(undefined, undefined, undefined, ...)
复制代码
由于Array构造函数会根据给定的arguments来建立一个数组(若是不是仅有一个参数且为数字的话), 经过Array.apply传入一个length为10的空数组则至关于, 把一个空数组中的每个元素的值逐个传入Array()方法, 而空数组中的每个元素 好比: emptyArr[0] 的值都是 undefined
为了便于理解这里写一个伪代码; 伪代码:
var arrayLike = {length: 2}
↓↓
Array.apply(null, arrayLike)
↓↓
Array(arrayLike[0], arrayLike[1]) // 把一个空数组中的每个元素的值逐个传入Array()方法
↓↓
Array(undefined, undefined) // 而空数组中的每个元素的值都为undefined
//最终输出 [undefined, undefined]
复制代码
这也就是为何能够经过Array.apply()方法能够生成一个可供forEach等方法遍历的数组
Array.apply(null, {length: 5})
// 上面这样写实际上等于下面这样写
Array(undefined, undefined, undefined, undefined, undefined)
// [undefined, undefined, undefined, undefined, undefined]
// 生成的数组里的元素都被初始化成了undefined,就能够被forEach等方法遍历了
复制代码
另外es6提供了一个新的api,Array.from()也能够作到相同的结果
如下是阮一峰老师的《ECMAScript 6 入门》的引用
Array.from方法还支持相似数组的对象。所谓相似数组的对象,本质特征只有一点,即必须有length属性。所以,任何有length属性的>对象,均可以经过Array.from方法转为数组
Array.from({length: 5})
// [undefined, undefined, undefined, undefined, undefined]
复制代码
es6的另外一种写法
Array(...Array(5))
// 或者
[...Array(10)]
// [undefined, undefined, undefined, undefined, undefined]
复制代码