0%

創建與宣告陣列 Array

Day 04

這次的鐵人賽,參考書籍有可拿來當枕頭的大犀牛「Javascript 大全」和「你所不知道的 JS」系列為主要參考,學習前端以來深深覺得有些書,程度不到來讀,真的很吃力,本人就是如此。但既然知道這些書都是許多大神推薦的書,那麼就試著了解,不懂的地方透過實作和請教前輩得到答案,也是頗好的學習方式,但本人不才,如有解釋錯誤的地方,還請各位海函啊。

前一篇我們有提到陣列可以做什麼,是不是對陣列有個比較清楚的概念?有些參考書籍會把陣列形容成有很多個格子的抽屜或盒子,這樣去解釋陣列也是頗具體的,但要記得一般來說,每個格子都會有連續的編號,也就是前幾篇提到的索引值(index)是「有序」的這件事情。但到底有序是不是絕對呢?記得曾經看過,把陣列的索引值改成字串的數字作法,例如:let arr = []; arr[“5”] = 42 會有什麼結果呢?我們先賣個關子。

當我們宣告一個陣列時,也同時在創建一個陣列,如果沒有考慮後續的處理問題,創建陣列是非常簡單的,但如果要讓陣列在後續可以很順利地被處理與運用,就不得不謹慎的考慮陣列裡的元素是什麼型別的問題了。

字面值宣告陣列

最簡單的創建陣列方式是使用陣列的字面值(array literal),也就是用一對中括號 [],把值放在[]中,並以逗號區隔陣列中的值(元素),再指定給一個變數。

空陣列

什麼都沒放,當然也可以。通常是先設一個空陣列,再將要放進去的值已不同的方法放入,列如 push();。

1
let emptyArray = [];

同型陣列

陣列裡面的值都是同類型的資料,這種陣列最好做後續的處理,處理過後的結果也最穩定。

1
let arrNumber = [2, 4, 24, 42];

非同型陣列

什麼資料型別都有的陣列, 不知道是什麼意圖 或許可以用物件來裝會比較清楚一些,不然只有你知道每個元素的意義。有沒發現陣列的結尾也有一個逗點,在 JavaScript 裡是被允許的,但並不會因為有這個逗點,而讓陣列的長度變長,或者是多一個空值。

1
let arrMixValue = ['Hi', 4.2, true, '24'];

包含運算式的陣列

陣列裡的值不一定是要常數,陣列裡面的元素也可以是任意的運算式,例如,某一個商品的定價是 42,我們想知道這個商品打七折、八折、九折的價錢,並把它放在陣列裡, 或許就可以用這個方法,但是,有時會有些意想不到的結果,這部分可以另外去查看 JavaScript 是如何處理運算子與數字的。

1
2
3
let unit = 42;
let rebateList = [unit, unit * 0.7, unit * 0.8, unit * 0.9];
//  [42, 29.4, 33.6, 37.800000000000004]

逗點造成的稀疏陣列

如果在宣告陣列時,夾雜了多個分隔的痘點,逗號和逗號之間沒有值,都會被視為是 undefined。

1
let arrNumber = [2, 4, , 24, , 42];

含有 undefined 的陣列

如果宣告陣列時,介於兩個逗號之間沒有值或空的,這個陣列就會成為稀疏陣列,這些空的元素會被填入 undefined,變成所謂的空插槽(empty slots),這些空的位置看似被填入了 undefined,但是在瀏覽器的開發工具 Console 使用同樣的語法,填入的卻是 Empty 而不是 undefined。在「你所不知道的 JS - 導讀,型別語文法」裡也有寫到這樣的現象,說明了在這裡產生的 undefined 和 arr[1] = undefined 不同,使用方法的結果也較不穩定,需要特別注意。

包含物件和陣列的陣列

在大全裡,有一個範例是陣列被宣告時,陣列裡的值如下,加好多料,有陣列也有物件,這真的超過本人的理解範圍,也真的不建議這麼寫。

1
2
3
4
let vrayMix = [
[0, { a: 1, b: 2 }],
[1, { a: 3, b: 4 }]
];

建構式宣告

另一種創建陣列的方式是使用 JavaScript 內建的建構式 Array() ,把建構式直接指定給變數,就成了陣列。
創建陣列有三種方法:

不帶引數就是空陣列

1.不帶引數的呼叫,這裡的引數指的是 new Array()括號內所放的值,結果同等於空陣列。

1
let arr = new Array(); // -> []

給長度仍然是空的

2.在內建的建構式 Array() 裡帶一個值數值,而這個值也會成為這個陣列的長度,且裡面的值都會是空值 undefined。

1
let arr2 = new Array(5); // -> [empty × 5]

陣列內容就在括弧裡

3.把要宣告的陣列內容,直接以引數的方式帶入建構式,感覺建構式的括號裡可以包山包海,放不同的型別資料也可以。但是放入時記得要把陣列的中括號[]拿掉。

1
let arr3 = new Array([1, 2, 3], 'hi', 42); // ->  [Array(3), "hi", 42]

總結:要用哪一種?

看了「Javascript 大全」和「你所不知道的 JS」系列,都是建議盡量少用建構式的方式去宣告或創建陣列,原因不是很清楚,但比較下來「字面值」宣告陣列的方式明顯比「建構式」宣告來的直覺與簡單。

建構式的陣列宣告與一般的陣列宣告本質上是相同的,唯一一點不同的是,如果宣告時我們只給一個參數,那麼字面值會把第一個參數當作是陣列裡第一個元素值,而建構式則會把第一個參數當作是陣列的長度,且只能給整數不能給小數點,不然會報錯,這點不可不注意。

1
2
let arr1 = [8]; // [8]  length: 1
let arr2 = new Array(8); // [empty x 8] length: 1

JS 很奇怪捏

在文章的開頭,有提到把陣列的索引值改成字串的數字作法,例如:let arr = []; arr[“5”] = 42 會有什麼結果呢?答案是:

1
2
3
4
5
let arr = [];
arr['5'] = 42;

console.log(arr); // (6) [empty × 5, 42]
console.log(arr.length); // 6

當我們這樣宣告時,JavaScript 並不會報錯,而直接把字串的數字轉成陣列長度,然後加上我們把 42 指定給它,JavaScript 直接把 42 放進陣列,長度因此變成 6,有猜對嗎?

但這只有字串的數字會有這種現象,如果是純字串,那麼字串就會被轉換成 key,而指定的值則會轉換成為 key:value 的形式。
因為 Javascript 的陣列不能用字串作為索引值。 當一個 Javascript 陣列是只能以數字作為索引值的,所以當我們設定以字串作為索引值的時候,實際上是在設置物件的屬性。

1
2
3
4
5
let arr = [];
arr['Hi'] = 42;

console.log(arr); // [Hi: 42]
console.log(arr.length); // 0

介紹了四天的陣列,有沒覺得膩?小菜才吃了四碟,明天我們就來介紹陣列唯一的屬性 length 與其他較輕鬆的話題吧!

如有需要改進的地方,拜託懇求請告知,我會盡量快速度修改,感謝您~