[JavaScript]-Array構造的數組使用map爲什麼失效?

img

[示例]編程

假設你須要生成一個從0到99的數組。你要怎麼作呢?下面是一種解法:數組

const arr = [];
for (let i = 0; i < 100; i++) {
  arr[i] = i;
}

看到這種使用傳統的for循環的方式會有點不大習慣。事實上,各類高階函數,像forEach, map, filter, reduce足以寫出各類漂亮的代碼。函數式編程

也許你尚未沉醉於函數式編程的美妙,那麼你會認爲上面的解法足矣。不過,若是你用太高階函數編程,你也許就會想:必定還有更加優雅的實現方法。函數

個人第一直覺就是:首選建立一個長度爲100的空數組,而後由map用index去初始化每個元素。在JavaScript中,你能夠用Array構造函數來建立數組:code

const arr = Array(100);

接下來你只須要用map就能夠解決問題了:對象

const arr = Array(100).map((_, i) => i);
console.log(arr[0] === undefined);  // true

但是,爲何第一個元素不是0而是undefined?索引

[解釋]ip

爲了理解爲什麼沒有生效,我須要首先講清楚一個很是重要的技術點。在內部,JavaScript數組其實是對象,對象裏面的屬性名是數字,對應數組的下標。舉個例子:回調函數

['a', 'b', 'c']

它實際上等價於:console

{
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
}

當你去訪問數組的第0個元素的時候,實際上訪問的是對象中屬性名爲0的元素。接下來咱們會解釋爲什麼剛剛的代碼沒有效果。

當你使用Array構造函數來新建一個數組,那麼它會建立一個新的數組對象,而且將長度length設定爲指定的值。可是,對象裏面沒有數組索引:

{
  //no index keys!
  length: 100
}

當你去訪問數組的第0個元素的時候,返回值爲undefined。但並非指第0個元素得值爲undefined,而是當數組下標不存在的時候,默認的返回值。

而且若是數組下標不存在的話,其實map函數並無真正的對每個元素執行操做。由於只有當下標存在的時候,map的回調函數纔會執行. console

[解法]

所以,咱們只須要在數組對象中構造出數組的下標就能夠了。最好的方法就是用展開運算符:

const arr = [...Array(100)].map((_, i) => i);
console.log(arr[0]);
// 0

使用展開運算符後的數組對象:

{
  0: undefined,
  1: undefined,
  2: undefined,
  ...
  99: undefined,
  length: 100
}

就能夠順利使用map函數了。

相關文章
相關標籤/搜索