今天在學習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]
複製代碼