博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Like Sunday, Like Rain - JavaScript运算符优先级
阅读量:6590 次
发布时间:2019-06-24

本文共 3891 字,大约阅读时间需要 12 分钟。

“JavaScript⾥的很多奇技淫巧,都来⾃于对运算符的灵活使⽤。”

说到运算符的优先级,我们往往会想到一张见过无数次却从来没背下来的表。因为没背下来, 所以往往会认为它很简单,只要拿不准的时候去看看就好。我曾经也是这么认为的,直到在一个明媚的下午,我对着这张遍,遇到了几个问题。我才发现我其实并没有把它搞定。

希望你也能有一个阳光明媚的下午,来解开心中的这些困惑。

1 运算符基础

我们先看一下完整的

这张表说明了两个问题:

1.1 优先级: 优先级高的运算符最先被执行

问题: 1 || 1 ? 2 : 3 ;     答案:2      解析:||的优先级高       相当于: (1 || 1 )? 2 : 3        而不是:  1 || (1 ? 2 : 3 )复制代码

1.2 关联性: 运算符执行时的方向。是从左向右,还是从右向左

问题:+function (){var a = b = 1;}();         console.log(b);           console.log(a);     答案:1   error    解析:赋值从右到左,var a = b = 1所以相当于         b = 1;         var a = b;         那有同学可能会问,为什么不是?         var b = 1;         var a = b;         还记得变量提升吗?var a = b = 1;在变量提升的时候,只会把a去声明,并不会执行赋值中的b。         所以要想把b也声明了就需要按照语法 var a=1 , b ;复制代码

现在我们仔细把优先级的题改一下

1 || fn() && fn() 复制代码

MDN上写的是优先级高的运算符最先被执行,我们都知道 ||是短路的,后边不会执行。那么这个最先被执行的含义是什么呢?

1.3 短路:

  • && 运算符的短路(a && b):如果a为假,b就不用执行了
  • | | 运算符的短路(a || b):如果a为真,b就不用执行了
问题:1 || fn() && fn()     答案:1  fn不会执行    解析:就是利用&&运算符的短路原理啊。复制代码

讲到这有些同学会觉得很简单啊,就是这样啊,看到短路后边就不用算了啊。也有的同学可能会有点懵,不是说好了, 优先级高的先被执行吗?明明&&的优先级高啊。哈哈,别吵吵,我们一起看下一题。

问题:var a = 42;         var b = "foo";         var c = 0;         c || b ? a : b ;  //  42           复制代码

刚才说短路的同学可能会说还是要参考优先级。刚才说优先级的同学可能一脸懵逼,静静地不想说话。那么我们开始今天的学习吧。

2 绑定

定义:运算符的优先级高先执行,并不是真正的执行,而是更强的绑定。

我们用上面来两个问题

1 || fn()  && fn()   //  &&的优先级高,所以将后边的绑定    1 ||(fn() && fn())  //  所以相当于1 和(fn() && fn())的值去逻辑或    1 ||(fn() && fn())  //  我们查表,逻辑或从左到右执行。    1 ||(fn() && fn())  //  左执行,1是真值,所以短路,后边不执行复制代码
问题: var a = 42;          var b = "foo";          var c = 0;          c || b ? a : b ;      答案:42    解析:c || b ? a : b ;     //查表  条件运算符权重是4,逻辑与符权重是6,所以逻辑与有更强的绑定         (c || b )? a : b ;   //(c || b )相当于条件运算符里的条件         (c || b )? a : b ;   //(c || b )值是0 ,所以值是 a 复制代码

好,我们在做两题巩固一下

问题: var a = 5;          var b = 5;          var c = 5+a+++b;          [ a , c ]    答案: [6, 15]    解析: b = 5+a+++b;          //查表  后置递增权重17 前置递增权重16          b = 5 +(a++)+ b;    //++优先级更高,所以和绑定a绑定在一起          b = 5 +(a++)+ b;    //根据语法后置递增先执行语句,后递增          b = 5 +(a++)+ b;    //执行语句时a是5,所以b是15          b = 5 +(a++)+ b;    //a在进行自增,得到6复制代码
问题: var a = 5;          var b = 5;          var c = ++a-b;          [ a , c ]    答案: [6, 1]    解析: var c = ++a-b;        //查表  前置递增权重和一元减权重都是16,从左往右执行          var c = ++a-b;        //根据语法前置递增先递增,后执行语句 a = 6          var c = ++a-b;        //执行语句时a是6,所以b是1复制代码

看到这,同学们可能恍然大悟,就这么回事啊。别急,我们来看下一题。 要解决这个问题,需要我们理解下一节的概念。

问题: var a = 42;          var b = "foo";          var c = 0;          a && b || c ? c || b ? a : c && b : a  复制代码

3 关联

定义:运算符的关联性去定义表达式的处理方向

来,用题说话

问题:a && b && c 的执行顺序    解析:(1)两个运算符都是&&,权重一样。所以这个时候就要看关联性。         (2)查表 &&的关联性是从左到右         (3)所以表达式应该是 ( a && b ) && c复制代码
问题:a ? b :c ? d : e 的执行顺序    解析:(1)两个运算符都是条件运算符,权重一样。所以这个时候就要看关联性。         (2)查表条件运算符的关联性是从右到左         (3)所以表达式应该是  a ? b :(c ? d : e )复制代码

好了,现在我们就可以轻松解决上面那个问题啦。

问题: var a = 42;          var b = "foo";          var c = 0;          a && b || c ? c || b ? a : c && b : a     答案: 42    解析:(a && b) || c ? c || b ? a :(c && b) : a    //首先查表逻辑与权重是6最高         ((a && b) || c) ? c || b ? a :(c && b) : a  //然后是逻辑或         ((a && b) || c) ? (c || b ? a :(c && b)) : a  //两个条件运算符,权重一样。关联性从右到左复制代码

啊、、有没有很开心 最后的最后,我们来讲一个释疑

4 释疑

哈哈,释疑顾名思义就是解释调疑惑的地方,那最好的办法就是加()。

如果你能够熟练运用优先级/关联的规则,你的代码能更简洁,许多框架都是这样写的,非常漂亮。

但是你要叫不准,那就加()吧,千万别逞能,美其名曰有助于代码的可阅读性。

优先级 运算类型 关联性 运算符
20 n/a ( … )
19 从左到右 … . …
从左到右 … [ … ]
n/a new … ( … )
从左到右 … ( … )
18 从右到左 new …
17 n/a … ++
… --
16 从右到左 ! …
~ …
+ …
- …
++ …
-- …
typeof …
void …
delete …
await …
15 从右到左 … ** …
14 从左到右 … * …
… / …
… % …
13 从左到右 … + …
… - …
12 从左到右 … << …
… >> …
… >>> …
11 从左到右 … < …
… <= …
… > …
… >= …
… in …
… instanceof …
10 从左到右 … == …
… != …
… === …
… !== …
9 从左到右 … & …
8 从左到右 … ^ …
7 从左到右 … | …
6 从左到右 … && …
5 从左到右 … || …
4 从右到左 … ? … : …
3 从右到左 … = …
… += …
… -= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
2 从右到左 yield …
yield* …
1 n/a ... …
0 从左到右 … , …

参考:

转载地址:http://vqkio.baihongyu.com/

你可能感兴趣的文章
国内航空业大数据新应用:星环助力厦门航空
查看>>
httpoxy漏洞远程攻击PHP Python应用
查看>>
解读非法泄露的数据和隐私的流入路径
查看>>
ImageMagick再爆DoS漏洞CVE-2017-8830 7.0.5及7.0.6版本受影响 波及多个Ubuntu Linux版本
查看>>
近几年前端技术盘点以及 2016 年技术发展方向
查看>>
RedHat Linux服务器安全配置细节
查看>>
大数据架构面临技术集成的巨大障碍
查看>>
智能中控:让“各自为政”的智能家居并肩作战
查看>>
安卓耗电之谜:罪魁祸首是谁?
查看>>
剖析大数据分析方法论的几种理论模型
查看>>
选择外部数据中心:云安全十问
查看>>
TalkingData携手中青旅联科建立旅游消费者大数据实验室
查看>>
APP推广之巧用工具进行数据分析
查看>>
你如何在浏览器中体验Ubuntu
查看>>
一分钟了解负载均衡的一切
查看>>
小鱼易连全系新品正式发布 引爆音视频会议行业核聚变
查看>>
认知计算可改进企业的13个关键功能
查看>>
大数据科技如何影响现代体育
查看>>
如何配置OVN路由器?
查看>>
当人工智能遇上大数据 第九届中国云计算大会——大数据与人工智能应用论坛吸睛亮点集结...
查看>>