當運算式有多個或多個類別的運算子時,我們會以運算子的 優先性
以及 相依性
來決定運算執行的順序與方向
優先性是運算子彼此之間的執行順序,而優先序高的運算子會優先執行,若優先性相同則以相依性規則執行
相依性決定運算子的執行方向,例如:由左至右執行
以下為常見運算子的優先性與相依性表格:
詳細可看 MDN - 運算子優先序
優先性 | 運算子 | 相依性 |
---|---|---|
16 | ++ … | 由右至左 |
16 | -- … | 由右至左 |
14 | … * … | 由左至右 |
14 | … / … | 由左至右 |
13 | … + … | 由左至右 |
13 | … - … | 由左至右 |
11 | … < … | 由左至右 |
11 | … > … | 由左至右 |
10 | … == … | 由左至右 |
10 | … === … | 由左至右 |
9 | … & … | 由左至右 |
6 | … && … | 由左至右 |
5 | 由左至右 | |
3 | … = … | 由右至左 |
當運算式中有多個不同類別運算子,先執行優先順序高的
var a = 2 * 2 + 2 * 3;
console.log(a);
*
優先性最高,而相依性為左至右,所以先執行 2 * 2
、2 * 3
,得出 var a = 4 + 6;
+
優先性較 =
高,所以執行 4 + 6
得出 10
=
相依性為右至左,所以 10
賦值到 變數 a
上console.log(1 < 2 < 3); // true
此例優先性相同,<
相依性由左至右執行, 1 < 2
為 true
,true
與數字做比較會自動轉型為 1
,又因 1 < 3
,所以答案為 true
console.log(3 > 2 > 1); // false
此例優先性相同,>
相依性由左至右執行 3 > 2
為 true
,true
與數字做比較會自動轉型為 1
,而 1 > 1
答案為 false
var a = 1;
var b = 2;
a = b = 3;
console.log(a, b); // 3 3
=
相依性為右至左,所以由 b = 3
開始執行b = 3
為表達式,會回傳值 3
變數 a
經由賦值運算子,將所回傳的 3
賦予至 變數 a
變數 a
接收的是b = 3
的回傳結果,並非取自於變數 b
的值
var a = {};
Object.defineProperty(a, 'b', {
value: 2,
writable: false,
});
a.b = 3;
console.log(a.b); // 2 - 因不能被賦寫
var c = 4;
c = a.b = 5;
console.log(a.b, c); // 2 5
變數 a
為一個空物件,在 變數 a
下新增 屬性 b
,設定 屬性 b
值為 2
,且不可寫入a.b = 3;
時,因已設定 writable: false
所以 a.b
不能夠被覆寫,會保持 2
的值,故賦予的值 3
,也因沒有效果被釋放掉變數 c
,賦予值 4
;c = a.b = 5;
,因 =
相依性由右至左執行,先執行 a.b = 5
,a.b
因不能被覆寫,會保持 2
的值,但因 a.b = 5
為表達式,會回傳值 5
a.b = 5
所回傳的值 5
會賦予至 變數 c
變數 c
的值為 5
,a.b
的值為 2
var a = {};
Object.defineProperty(a, 'b', {
value: 2,
writable: false,
});
Object.defineProperty(a, 'c', {
value: 3,
writable: false,
});
var d = 4
d = a.c = a.b = 5;
console.log(d, a.b, a.c); // 5 2 3
變數 a
為一個空物件,在 變數 a
下新增 屬性 b
及 屬性 c
,設定 屬性 b
值為 2
,設定 屬性 c
值為 3
,且皆不可寫入變數 d
,賦予值 4
;d = a.c = a.b = 5;
,=
相依性由右至左執行a.b
、 a.c
都不會被覆寫,所以 a.c
先接收 a.b = 5
表達式所回傳的值 5
,得出 a.c = 5
表達式並回傳值 5
a.c = 5
所回傳的值 5
會被賦予至 變數 d
變數 d
的值為 5
,a.b
的值為 2
,a.c
的值為 3