(Day9) 运算子中的优先性及相依性

运算子优先性 (Precedence)

先来看一个范例

4 / 2 * 2 + 2 //6

这段程序码执行下来答案是 6 ,很符合我们对数学先乘除後加减的概念。

但在 JavaScript 中还有其他运算子,扣掉我们较熟悉的算数使用的算数运算子,如何知道其他运算子的使用顺序呢?

MDN 文件中就有提供相关的表格。

在文件中我们可以看到 + 号算数运算子优先性是 13 ,*/ 除,是 14 ,因此也会是我们熟知的先乘除後加减,但 JS 是怎麽判断范例中先 /* 呢?

运算子相依性 (Associativity)

这时就要介绍运算子另一个特性,『相依性』,而相依性的特性就是,如果运算子是相同优先性,那麽 JavaScript 会根据设定,从指定方向开始执行,从文件上也可以看到 */ 的算数运算子是 『从左至右』。

再来看看一个满常见的前端面试问题:

1 < 2 < 3 // true

答案是 true 跟我理解一般理解的一样,那麽稍微调整一下顺序:

3 > 2 > 1 //false

这时就变成 false 了,这是因为相依性的特性,会让上面范例在执行整段程序码是分开的,会先执行 3 > 2 接者才会执行 2 > 1
但上面的说法其实不太正确, 3 > 2 这段是表达式,而表达式的特性就是会回传值。
3 > 2 这段表达式回传的会是 true ,因此实际上会是 true > 1 ,而不是我们原先认为的 2 > 1
所以上面这一段在 JavaScript 中是这样的:

3 > 2 
true > 1

( true 会隐含转型变成 1 , 1 > 1 因此最後回传 false )

再来根据表达式特性再提一个赋值状况:

var a = 1;
var b = 2;
a = b = 3;

结果我们查询 a 、 b 值都会是 3
在我们看来会是他的执行顺序会是:

var a = 1;
var b = 2;

b = 3;
a = b

但要注意这个执行顺序并不正确,这边实际上的情况是:

b = 1 时,因为这段是表达式,所以会回传 1 ,接者才是 a 被赋予回传的 1
所以 a 被赋予的实际上是 b = 1 回传的值。

我们可以使用 Object.defineProperty() 锁定物件属性中的值 来验证这个观念:

var obj = {};

Object.defineProperty(obj, 'test', {
  value: 0,
  writable: false,
})

这个写法会绑定物件 objtest 属性的值,接者新增一个变数来替换 obj 中的 test:

var obj = {};

Object.defineProperty(obj, 'test', {
  value: 0,
  writable: false,
})

var num = 1
obj.test = num
obj.test //0

确认 obj.test 是无法被更改的,接着使用连续赋值的动作看看结果如何:

var obj = {};

Object.defineProperty(obj, 'test', {
  value: 0,
  writable: false,
})

var num = 1
num = obj.test = 5566
console.log(num,obj.test) // ???

结果回传的是 55660,这是因为 5566 虽然没有成功赋予到 obj.test 上,但是 obj.test = 5566 这段表达式会回传 5566,因此 num 最後是获得这个回传的 5566

参考资料


<<:  D3 Django 资料夹结构与设定说明

>>:  D8 第四周 (回忆篇)

既熟悉又陌生的字元集与比较规则

我们都知道电脑实际储存的是二进位资料,那是怎麽储存字元的呢? 可以想像的就是必须让字元映射成二进位资...

企划实现(26)

在firebase制作登入系统 可以使用myRef.child("member"...

岔路上的风景 - 递回

在学习JS的路上意外接触到了递回的概念,一开始觉得这是什麽鬼东西,回圈用的好端端的,为什麽需要学习难...

IT 铁人赛 k8s 入门30天 -- day15 k8s Workload 简介

前言 今天要讲的是 k8s 丛集对於 Workload 管理做讲解 Pod 的管理 以下将会解释一些...

全端入门Day30_结尾

昨天介绍了Golang的http,今天是这30天的结尾。 这30天,我收获良多因为我觉得这是一个毅力...