Array.apply生成數組小結

發現問題

今天在學習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]
複製代碼
相關文章
相關標籤/搜索