[JavaScriptWeird]No.15 運算子的相依性與優先性

前言

上一篇我們大概了解了什麼是運算子,這節要來討論運算子的相依性與優先性這兩個非常重要的名詞。它們看起來很複雜,但其實並不。

運算子優先性 ( Operator Precedence )

運算子優先性表示「哪個運算子優先被運算」,是 JavaScript 用來判斷當同一行程式碼有不只一個運算子時,決定優先權的方式。具有高優先性的運算子會先計算依序執行到低優先性的運算子。

運算子相依性 ( Operator Associativity )

運算子相依性表示「運算子被計算的順序」,有分成從左到右的「左相依性」或是右到左的「右相依性」。

這代表當多個運算子有相同優先性時,會按照怎麼樣的順序被計算

1
2
var a = 3 + 4 * 5;  
console.log(a); // 23

我們來解釋一下為什麼答案會是 23 。

以數學的四則運算來看,先「乘除」後「加減」有「括號先算」,JavaScript 同樣也有規則,這個例子因為有三個運算子,所以需要呼叫三個函式,但是 JavaScript 並不會同時計算它們。也就是說,這三個函式會按照優先權決定誰先被呼叫。

MDN 的運算子優先性網頁

透過查詢,我們可以得知以下:

第一欄是運算子的優先性,數字越高代表有越高的優先權。
第三欄是運算子的相依性,決定當優先權相同時該如何運算的順序。

從這表格得知,「*」優先性為 14,「+」優先性為 13 ,因此「*」函式會優先被 JavaScript 呼叫,接著才是「+」。

1
2
var a = 3 + 4 * 5;  
console.log(a); // 23

計算的順序為 4 * 5 計算後回傳 20 , 然後 3 + 20 回傳 23 再將值設定給 a

如果完全不按照優先性,計算上會產生相當大的變化,因此優先性很重要。

來個相依性的例子:

1
2
3
4
5
var a = 2, b = 3, c = 4  
a = b = c;
console.log(a); //4
console.log(b); //4
console.log(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

0%