Array 可能跟你想的不一樣(上)

osk2
osk2
Nov 4 · 6 min read
Photo by Caspar Camille Rubin on Unsplash

前陣子在 JavaScript 群組看到一個很有意思的問題:

const ary = [undefined, undefined, undefined];ary.forEach(v => {
console.log(v);
});
// 印出三次 undefined
const ary2 = new Array(3);
ary2.forEach(v => {
console.log(v);
});
// 這裡卻什麼都沒印出來

這問題可以拆成兩部分

  1. new Array() 建立的到底是什麼?跟 [] 不一樣嗎?
  2. 為何 new Array(3) 執行 forEach() 不會印出三次 undefined?

礙於篇幅(對,我知道太長你們會直接 End),上集只會專注在解釋第一點,forEach() 的部分就留到下集吧 👇

[undefined, undefined, undefined] 跟 new Array(3) 究竟有什麼差別?

陣列的建立

一般我們都會使用 [] 來建立陣列,也就是傳說中的 Array Literal Notation,但這跟 new Array() 有什麼不同之處嗎?

要解釋這個問題,我們得先了解 new Array() 是如何建立陣列的。先讓我們在 console 裡試試:

咦?竟然是 empty×3

咦?empty 代表什麼?跟 undefined 又有什麼不同?

註:這裡以 Google Chrome 為例,其他瀏覽器不一定會顯示為 empty

根據我們犀利的觀察,用 [] 建立的陣列確實有三個 undefined,new Array() 卻沒有,那兩者的差異是什麼呢?

我們知道 JavaScript 中除了原始型態(primitive type),其餘就是物件

既然陣列也是物件的一種,那我們試著把物件屬性印出來看看:

Object.getOwnPropertyNames([undefined, undefined, undefined]);
// ["0", "1", "2", "length"]
Object.getOwnPropertyNames(new Array(3));
// ["length"]

很明顯的,用 new Array() 建立的陣列只有 length 屬性,陣列中沒有任何數值存在

到這裡真相已經大白了,原來 new Array(3) 會建立一個只有 length 屬性的陣列

如果我們要用 Array Literal Notation 建立一個像 new Array(3) 的陣列,這樣做才是對的

new Array(3) // [empty × 3]
[,,,] // [empty × 3]

也因此 [undefined, undefined, undefined] 和 new Array(3) 根本是不同的東西呀

new Array() 的坑

雖然 new Array() 表面上看起來沒這麼糟,但其實還是有兩個缺點:

  1. 對各種傳入參數的處理行為不一致
  2. 比起 [] 多打了很多字

關於傳入參數的處理行為,根據 MDN 的說明,new Array() 可以接受無限多個參數

節錄 MDN 對 Array 的說明

如果傳入的是整數 N,且只有一個參數時,那就會建立一個 length 為 N 的空陣列。如果 N 為負數或非整數則會噴 RangeError

若是傳入的是多個整數,或其他類型的參數則會視為陣列值

直接來看個範例:

new Array('a')     // ["a"]
new Array(3) // [empty×3]
new Array(1, 2, 3) // [1 ,2, 3]
new Array(-1)
new Array(5.6)
// 上面這兩個都會導致 RangeError 錯誤

要 new Array() 何用?

看到這裡你心裡一定覺得 new Array() 這麼沒用,到底哪裡才派得上用場?

直接說答案

  1. 用於建立未知長度的陣列
  2. 某些小技巧蠻挺實用的

new Array() 其中一個不可取代的優點就是可以將變數作為參數傳入,因此我們就能建立未知長度的陣列了

const arrayLength = 10;new Array(arrayLength);

更新:

經過 JacaScript.tw 社員糾正我才知道上面說不可取代是錯的,詳見下圖

[] 也能預先設定 length
[] 也能預先設定 length

其他就是一些較不常用的小技巧,像是:

建立九個空格的字串

new Array(10).join(' ');

至於為什麼會是九格空格就讓你自己去查 ECMAScript 定義,或是看下集揭曉囉

或是建立一個填滿 5566 的陣列

new Array(3).fill('5566'); // ["5566", "5566", "5566"]

References

osk2

Written by

osk2

Just a geek.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade