JavaScript 概念三明治(一)

物件 Object

物件是JavaScript 裡面很重要的型別,在其他語言裡的物件可能有不一樣的意思,但在JavaScript裡面,物件就是「一連串鍵與值配對(key-value pairs)的組合」。換句話說,這意味著物件是由一個個的名稱與一個個的對應內容聚集在一起後形成的結果,這個物件的鍵名又被稱為物件的屬性(property),屬性的用途跟變數有一點相像,都是讓開發者在存取時有一個獨特的名稱,用以區別不同內容。

創造一個物件

一個物件最簡單的宣告方式,就是在賦予變數時,用兩個大括號,將即將宣告的物件包裹起來,並用冒號來區分物件內的屬性名稱與想要存放的數值內容。範例如下:

物件屬性的存取

一般的變數在宣告並被賦值後,我們就用該變數名稱來表示要存取對應內容。而這個變數如果存取的內容是物件,則可以搭配中括號「[]」,或是小數點符號「.」來拿到物件裡面某個屬性的內容:

anObject["key1"] --> 用中括號來存取物件屬性的內容
abObject.key1 --> 用小數點符號來存取物件屬性的內容

陣列 Array

陣列在許多程式語言都會出現。它跟物件有一點點像,但是使用的方式有些差異。如同前面提到的,如果物件是一連串的名稱與對應內容組合而成的型別,那麼陣列就是「把一系列的數值放在一起形成的組合」。意即可以先把陣列看成沒有屬性的物件,只是陣列並非像物件那樣是用大括號來宣告。
創造一個陣列
使用中括號就能簡單宣告出一個陣列,並在中括號內用逗點區隔想要存放的各個值,與物件一樣,陣列可以存放多於一個以上的數值。

var array = ["內容一", "內容二"];

與物件屬性可以存放的內容相同,對於陣列裡面可以存放的內容,沒有型別上的限制,想要在陣列裡面放數字、字串、布林、物件或甚至是另外一個陣列,都是可以的。通常存放陣列裡面的數值,我們會用「元素」(element)來稱呼。
存取陣列的元素
存取陣列元素的方法跟物件一樣,可以使用中括號來表示。但是陣列不像物件那樣有明確的屬性可以知道要對哪一個內容作存取,該可麼辦呢?在陣列裡面的處理方式是,既然沒有明確的名稱,那麼就從第一個元素開始,給每一個元素一個足以區別內容的號碼,我們稱之為「索引」(index),陣列的這個號碼,是從0開始算的。
存取陣列的長度
陣列元素的長度可以用.length來取得,它的用法就跟存取物件屬性一模一樣。事實上,陣列背後的實作也是以物件來達成,只是使用的方式不一樣而已。

var array = ["1", "2", "3"];
console.log(array.length);
//3

函式宣告

函式最簡單的使用方式是透過function這個關鍵字來告訴JavaScript你想要宣告的函式。與變數一樣,函式在一般情況下也必須具有名稱才能讓JavaScript知道你想呼叫(執行)哪一個函式。
至於函式執行後回傳的結果則透過return來決定要回傳內容是什麼,而就像前面提到的一樣,return不一定要存在於函式的內容中,只不過如果在函式內沒有任何return被使用,或是有return但後面沒有任何要回傳的值,JavaScript都會自動幫你將回傳的值設置為undefined,所以可以把一個函式回傳的預設值當作是undefined

變數宣告

ES6出現了兩個新的變數宣告的關鍵字,也是目前實際產品開發中最常使用到的兩個語法,它們分別是let以及const。在前面則是用var來處理。
let
let其實與var差不多,與var不同是宣告變數的範疇、以及不能被重複宣告。  var是函式範疇,而let是區塊範疇 

let 是區塊範疇
區塊範疇相比於var的函式範疇,究竟有什麼優缺點呢?一個很明顯的好處就是,能夠更有效避免變數意外地被修改或覆蓋。
var是函式範疇
當我在全域宣告一個變數i,並在後面使用了for迴圈,for迴圈裡面的條件判斷也用到另外一個新的宣告的i,但是你會發現在for條件判斷用i其實在迴圈進行時也無意間對外面的全域變數進行了修改,最後,外面的變數i的內容就跟著變成10。而若使用const和let,這個問題就不會發生。
const和let的範疇則是一樣的,那麼const和let相較起來又有什麼差異呢?
const
const這個字本身意味著常數。它的範疇與let相同,都屬於區塊範疇,但是與let布一樣的是,使用const宣告變數在第一次宣告,並被指派後,就不能修改。也就是說,使用const所宣告的變數,只能夠被讀取。
使用const宣告變數時,一定要跟著一起指派內容。它與var或let不一樣,可以指宣告變數名稱而不給值。若你使用const時這麼做的話,就會出現錯誤。
而上面講到const所宣告的變數無法再重新指派的規則,其實有一個看起來像是例外的情況,那就是當const與物件、陣列一起使用時,會有這樣的情形發生:
看到了嗎?使用const所宣告的變數內容若是物件,則該物件裡的屬性還是能夠被存取跟修改,這看來很像是在對該變數內容作修改,其實並沒有。當變數被宣告並且存放的數值是一個物件時,所帶給變數的並不是物件本身的內容,而是物件存放的記憶體位置。
所以只要該變數所參考的記憶體位置保持一致,就不會有問題。而換另外一個角度來看,若我重新對const所宣告的變數指派另一個物件,那是會報錯的。