前言
上一篇我們大概了解了什麼是運算子,這節要來討論運算子的相依性與優先性這兩個非常重要的名詞。它們看起來很複雜,但其實並不。
運算子優先性 ( Operator Precedence )
運算子優先性表示「哪個運算子優先被運算」,是 JavaScript 用來判斷當同一行程式碼有不只一個運算子時,決定優先權的方式。具有高優先性的運算子會先計算依序執行到低優先性的運算子。
運算子相依性 ( Operator Associativity )
運算子相依性表示「運算子被計算的順序」,有分成從左到右的「左相依性」或是右到左的「右相依性」。
這代表當多個運算子有相同優先性時,會按照怎麼樣的順序被計算
1
2 var a = 3 + 4 * 5;
console.log(a); // 23
我們來解釋一下為什麼答案會是 23 。
以數學的四則運算來看,先「乘除」後「加減」有「括號先算」,JavaScript 同樣也有規則,這個例子因為有三個運算子,所以需要呼叫三個函式,但是 JavaScript 並不會同時計算它們。也就是說,這三個函式會按照優先權決定誰先被呼叫。
MDN 的運算子優先性網頁
透過查詢,我們可以得知以下:
第一欄是運算子的優先性,數字越高代表有越高的優先權。
第三欄是運算子的相依性,決定當優先權相同時該如何運算的順序。
從這表格得知,「*」優先性為 14,「+」優先性為 13 ,因此「*」函式會優先被 JavaScript 呼叫,接著才是「+」。
1 | var a = 3 + 4 * 5; |
計算的順序為 4 * 5 計算後回傳 20 , 然後 3 + 20 回傳 23 再將值設定給 a
。
如果完全不按照優先性,計算上會產生相當大的變化,因此優先性很重要。
來個相依性的例子:
1 | var a = 2, b = 3, c = 4 |
優先性我們已經知道了,「=」的優先性為 3,這個例子來說,運算子的優先性都是一樣的,那麼接著看相依性,「=」為「右相依」 (right-to-left),是用來傳入值的運算子。
也就是它會先呼叫這邊的「=」運算子
1 | b = c; |
這會讓 b
的值等於 c
,而 c
的值為 4 ,因此「=」函式回傳 4 給 b
。
同理,接著執行另一個「=」函式運算
1 | a = b; |
受到上一個「=」函式影響此時的 b
為 4 ,因此這次的「=」函式將回傳 4 給 a
。
還記得文中有提到數學有「括號先算」的例子嗎?
在 JavaScript 中也是有的,可以查到「括號」的優先性是 20 ,它的作用是區分出一個群組,將被包覆住的東西永遠優先被計算。
1
2 var a = (3 + 4) * 5;
console.log(a); // 35