這是一門在Udemy 課程,是同學介紹的。主要是因為想要運用到過年前這段時間好好的增進自己的JavaScript的基礎能力,讓自己能往前端工程師更近一步。主要還是會以筆記的形式做呈現!
在進入主題前,我們先聊聊JavaScript
在剛開始接觸JavaScript時,常常會聽到有人說JavaScript 弱型別 的程式語言,那時候的想法就是因為JavaScript 不嚴謹以及他的型別會自動轉換,這個觀念一直跟著我直到2023的今天我才知道這個觀念『不完全正確』
JavaScript 是動態型別加弱型別
靜態型別 vs 動態型別
1 | in Java(static typing): |
編譯式語言多半是靜態語言,Java 和 C# 是其中的代表。
這類語言在型別的管理上十分嚴謹,在語法撰寫時就會要求對變數型別有明確定義,有時讓人覺得囉嗦;但相對的,一旦有變數誤用或資料型態上的 Bug,在編譯時期就能發現,降低執行時期的風險。
1 | in JavaScript (dynamic typing): |
在程式執行過程才會進行資料型態的檢查或確認,因此直譯式語言都是動態語言。如 Python、PHP、Ruby,還有 JavaScript,都屬於此類語言。
這類語言在程式編寫時,不用花太多心思在宣告型別的語法上,簡潔而靈活,可以在過程依需求任意改變型別,做到十分靈活的變數處理;但相對缺乏對當前變數的型別限制,當執行到某一行程式時,無法絕對肯定變數現在放了什麼類型的值時,容易造成非預期的執行可能性,導致非預期的執行結果。
強型別 vs 弱型別
- 強型別(strongly typed):偏向不容許隱性型別轉換,型別檢查上較為嚴格。
- 弱型別(weakly typed):偏向容許隱性型別轉換,型別檢查上較為寬鬆。
所謂的隱性型別轉換如下:
1 | const a = 1; |
在可以隱性型別轉換的程式語言(如JavaScript)會因為變數是number + string,兩個型別不同而自動把第一個參數轉換成string,因此輸出結果就會是:12(這是字串)
但如果是在不可以隱性型別轉換的程式語言(如Java),就會直接噴錯
因此動態型別加上過於寬鬆的弱型別,就有人認為是 JavaScript 最叫人頭痛的萬惡根源。
那JavaScript 有哪些型別?
答案是2個:Primitive type 跟 object。分法很簡單只要不是Primitive type就是屬於 object,XD。
說正經的,Primitive type總共有7種,只要不屬於這7種的就是object。下列就是7種Primitive type:
- undefined: you shouldn’t set a variable to this
- null:you can set a variable to this
- boolean
- number
- string
- symbol
- bigint
說了這麼多終於要進入主題了,先來做名詞解釋,今天的主題可以分成3個不同的單字:operator、precedence、associativity。
Operator
可以稱為運算子,也就是我們在數學上常看到的運算符號。
1 | var a = 3 + 4 |
這段簡單的code中 + 就是運算子。
但這時候有一個問題,為什麼JavaScript會知道這段code要相加?
我們必須要了解他的底層:
當JavaScript引擎看到+這個運算符號時,他會去呼叫下面這個函式(+其實是一個函式)
1 | function add(a, b) { |
但我不用add命名,而是用+
1 | function +(a, b) { |
因此,這段code其實會是長這樣:
1 | var a = +(3, 4) |
但由於這樣寫實在太麻煩了,因此就有了以下這些寫法:
Prefix Notation: + 3 4
Infix Notation 3 + 4
Postfix Notation 3 4 +
像我們因為從小就是用3 + 4這樣的方式來讀,因此採用 Infix Notation會方便我們閱讀
但記住本質上他還是一個有兩個參數的函式調用
precedence
precedence(優先權):哪個運算子會被優先呼叫。
在同一行程式中,如果不只有一個運算子時,運算子會依優先權的高低被呼叫,而 JavaScript 會先處理高優先權的運算子,然後依序到低優先性權運算子。
associativity
associativity(相依性):運算子被呼叫的順序,有分為左相依性 (從左到右) 和右相依性 (從右到左)。
當同一行程式中,我們有多個相同優先性的運算子時,我們就要看相依性是如何,來判斷是從左到右還是從右到左呼叫。
了解這些名詞的意思後我們可以繼續往下走。
這是一段非常簡單的code:
1 | var a = 3 + 4 * 5; |
小時候都學過先乘除後加減,因此答案很簡單是:23。
但在程是上是怎麼算出來的?
這邊要記住所有的運算符號其實都是function,因此這段code可以看成是一組2個function的調用,又加上JavaScript引擎是 synchronous處理code,所以他會分段調用優先權較高運算子,因此會先調用*(優先權13)再調用+(優先權12)所以才會得到23。
了解基礎後我們來看看下個案例:
1 | var a = 2, b = 3, c = 4; |
為什麼全部都是4呢?
因為associativity,讓我們看到連結的表單。當今天我們在程式碼上看到 = 時,請把他看作是賦值運算子。因此我們找到賦值的欄位可以看到他的associativity是由右至左,因此我們在這行code要先處理的是b = c。
所以實際的code換成比較好閱讀會是:
1 | var a = 2, b = 3, c = 4; |
由於這些是屬於number,因此我們直接傳值,所以才會輸出全部都是4。
參考資料: