[Day15] 优先性与相依性

当运算式有多个或多个类别的运算子时,我们会以运算子的 优先性 以及 相依性 来决定运算执行的顺序与方向

优先性 (Precedence)

优先性是运算子彼此之间的执行顺序,而优先序高的运算子会优先执行,若优先性相同则以相依性规则执行

相依性 (Associativity)

相依性决定运算子的执行方向,例如:由左至右执行

优先性与相依性表格

以下为常见运算子的优先性与相依性表格:

详细可看 MDN - 运算子优先序

优先性 运算子 相依性
16 ++ … 由右至左
16 -- … 由右至左
14 … * … 由左至右
14 … / … 由左至右
13 … + … 由左至右
13 … - … 由左至右
11 … < … 由左至右
11 … > … 由左至右
10 … == … 由左至右
10 … === … 由左至右
9 … & … 由左至右
6 … && … 由左至右
5 由左至右
3 … = … 由右至左

优先性与相依性范例

范例1

当运算式中有多个不同类别运算子,先执行优先顺序高的

var a = 2 * 2 + 2 * 3;
console.log(a);
  • * 优先性最高,而相依性为左至右,所以先执行 2 * 22 * 3,得出 var a = 4 + 6;
  • + 优先性较 = 高,所以执行 4 + 6 得出 10
  • 最後 = 相依性为右至左,所以 10 赋值到 变数 a

范例2

console.log(1 < 2 < 3); // true

此例优先性相同,< 相依性由左至右执行, 1 < 2truetrue 与数字做比较会自动转型为 1,又因 1 < 3,所以答案为 true

范例3

console.log(3 > 2 > 1); // false

此例优先性相同,> 相依性由左至右执行 3 > 2truetrue 与数字做比较会自动转型为 1,而 1 > 1 答案为 false

范例4

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 的值

范例5

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 = 5a.b 因不能被覆写,会保持 2 的值,但因 a.b = 5 为表达式,会回传值 5
  • a.b = 5 所回传的值 5 会赋予至 变数 c
  • 变数 c 的值为 5a.b 的值为 2

范例6

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.ba.c 都不会被覆写,所以 a.c 先接收 a.b = 5 表达式所回传的值 5,得出 a.c = 5 表达式并回传值 5
  • a.c = 5 所回传的值 5 会被赋予至 变数 d
  • 变数 d 的值为 5a.b 的值为 2a.c 的值为 3

参考文献

六角学院 - JavaScript 核心篇

MDN - 运算子优先序


<<:  【设计+切版30天实作】|Day16 - 进入切版前的前置作业之列出设计稿上的数据

>>:  Day 15 conda 介绍与使用

Android一键更换主题套件

前言 前阵子看了bilibili上的一些技术相关影片,码牛学院的公开课程 Android动态加载技术...

Swift纯Code之旅 Day20. 「ViewController好乱(2) - MVC画面分离」

前言 昨天已经将要用来实作MVC分离的范例完成了,那今天就马上来实作MVC分离吧! 实作 首先先创一...

Day03 永丰金API 基础流程 -- Nonce

每家金流的流程都不太一样,但基本上有牵扯到金钱的东西,肯定会有一堆验证机制, 我们先看一下永丰金的流...

DAY29 - 做专案的心态

工作到现在以来,从乙方公司到成为公司内部的乙方单位,工作的历程比较倾向是用一个个专案堆叠而成。倒数第...