應該不會有人覺得我今天要講scope chain,雖然我昨天斷在這個地方,但那真的有點難,我打算放在比較後面來複習XD
今天主要是來講 運算子(Operator) 以及他們的 優先權(precedence) 跟 相依性(associativity)
運算子(Operator),也就是我們在數學上常看到的運算符號。
var a = 3 + 4
這段簡單的code中 + 就是運算子。
但這時候有一個問題,為什麼JavaScript會知道這段code要相加?
我們必須要了解他的底層:
當JavaScript引擎看到+這個運算符號時,他會去呼叫下面這個函式(+其實是一個函式)
function add(a, b) {
return
}
但我不用add命名,而是用+
function +(a, b) {
return
}
因此,這段code其實會是長這樣:
var a = +(3, 4)
但由於這樣寫實在太麻煩了,因此就有了以下這些寫法:
Prefix Notation: + 3 4
Infix Notation 3 + 4
Postfix Notation 3 4 +
像我們因為從小就是用3 + 4這樣的方式來讀,因此採用 Infix Notation會方便我們閱讀
但記住本質上他還是一個有兩個參數的函式調用
precedence(優先權):哪個運算子會被優先呼叫。
在同一行程式中,如果不只有一個運算子時,運算子會依優先權的高低被呼叫,而 JavaScript 會先處理高優先權的運算子,然後依序到低優先性權運算子。
associativity(相依性):運算子被呼叫的順序,有分為左相依性 (從左到右) 和右相依性 (從右到左)。
當同一行程式中,我們有多個相同優先性的運算子時,我們就要看相依性是如何,來判斷是從左到右還是從右到左呼叫。
下面這張圖是來自[MDN]
我們可以清楚看到剛剛我們所介紹的運算子(Operator) 、 優先權(precedence) 跟 相依性(associativity)
了解這些名詞的意思後我們可以繼續往下走。
在MDN 上有列出十種的運算子分類,這邊就不一一列出,大家有興趣可以直接到MDN去查看。
這邊主要介紹最常見的五個運算子:
今天這篇會先以前三個,剩下兩個是明天的內容。
包含了最基本的數學四則運算的符號,讓你可以對兩組值(value)進行加、減、乘、除。
算術運算子比較容易讓人弄不清楚的是遞加++
和遞減--
。
你會在程式碼裡面看到兩種寫法(+跟-觀念相同所以只用+舉例):
let x = 3
console.log(x) // 會印出 3
console.log(x++) // 會印出 3 ( 將 ++ 寫在變數後面 )
console.log(x) // 會印出 4
console.log(++x) // 會印出 5 ( 將 ++ 寫在變數前面 )
兩種都是代表「將 x 的值加上1」,但差別就在於:
console.log(x++)
的執行順序是:先列印出 x
的數值後,再進行 x = x + 1
的動作;
console.log(++x)
的執行順序是: x
的數值會先進行 x = x + 1
的運算,再列印結果。
在變數那章節有提到 =
這個符號,要把它看作是賦值,因為它是一種賦值運算子。
比較運算子陳述的是邏輯關係,他會對前後的 value 進行比較,然後回傳 boolean 值,也就是 true
或是 false
。
這部分最讓我們困惑的應該就是 ==
跟 ===
以及 !=
跟 !==
吧,其他其實跟數學差不多。
==
我們可以說:他是一個寬鬆的等於,直接看例子:
console.log(1 == '1')
剛學完資料型別的我們想必很清楚知道答案吧,答案就是false
……什麼!!!為什麼是true
!!!
因為使用**==**
不會特別判斷兩邊的資料型別是否不同,因此會發生許多難以掌握的狀況。
而使用 **===**
則會進一步比較資料型別是否相等,因此在撰寫 JavaScript 時一定要記得使用 **===**
。
在 重量級著作 JavaScript: The Good Parts 裡,Douglas Crockford 說得非常清楚:「我的建議是永遠不要使用這對邪惡的雙胞胎 (指 ==
和 !=
),永遠使用 ===
和 !==
。」
既然都瞭解了運算子(Operator) 、 優先權(precedence) 跟 相依性(associativity),以及3種運算子,這邊來一些進階的題目。
先暖身:
var a = 3 + 4 * 5;
小時候都學過先乘除後加減,因此答案很簡單是:23。
但在程式上是怎麼算出來的?
這邊要記住所有的運算符號其實都是function,因此這段code可以看成是一組2個function的調用,又加上JavaScript引擎是 synchronous處理code,所以他會分段調用優先權較高運算子,因此會先調用*
(優先權13)再調用+
(優先權12)所以才會得到23。
了解基礎後我們來看看下個案例:
var a = 2, b = 3, c = 4;
a = b = c;
console.log(a) //4
console.log(b) //4
console.log(c) //4
為什麼全部都是4呢?
因為associativity,讓我們看到連結的表單。當今天我們在程式碼上看到 = 時,請把他看作是賦值運算子。因此我們找到賦值的欄位可以看到他的associativity是由右至左,因此我們在這行code要先處理的是b = c。
所以實際的code換成比較好閱讀會是:
var a = 2, b = 3, c = 4;
b = c;
a = b;
由於這些是屬於number,因此我們直接傳值,所以才會輸出全部都是4。
就像前面說的,今天這篇會先介紹前面三個運算子,剩下兩個是明天的內容。
是因為加上去篇幅會太長,才忍痛分成兩篇的,絕對不是為了湊天數的XD
所以,明天見摟~