iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 4
2
Day 4

總是要出來見世面的,但不講名字怎知你是誰?

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

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

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

字面值宣告陣列

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

空陣列

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

let emptyArray =[]; 

同型陣列

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

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

非同型陣列

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

let arrMixValue = ["Hi", 4.2, true, "24",]

包含運算式的陣列

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

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

逗點造成的稀疏陣列

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

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

含有 undefined 的陣列

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

包含物件和陣列的陣列

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

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

建構式宣告

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

不帶引數就是空陣列

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

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

給長度仍然是空的

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

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

陣列內容就在括弧裡

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

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

總結:要用哪一種?

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

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

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

JS 很奇怪捏

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

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 陣列是只能以數字作為索引值的,所以當我們設定以字串作為索引值的時候,實際上是在設置物件的屬性。

let arr = []; 
arr["Hi"] = 42;

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

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

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


上一篇
JS 陣列 Array 可以做什麼、裝什麼有差嗎?
下一篇
JS 陣列 Array 屬性 length 的真面貌
系列文
JavaScript之一定要了解的 Array 與方法34

1 則留言

0
janshawn
iT邦新手 5 級 ‧ 2019-10-24 08:11:18

let arr2 = new Array(8); // [empty x 8] length: 1
想問文章中的程式碼 那個lnegth是不是打錯了 length應該是要8嗎?

tsuifei iT邦新手 5 級 ‧ 2019-10-25 06:31:57 檢舉

謝謝你來看文章,這裏 length 是 1 錯喔。 你是對的 ! 我搞錯了這部分了,真不好意思~ 馬上修改~
感謝!

我要留言

立即登入留言