web/docs/front-end/js-operator-priority.md

5.2 KiB
Raw Blame History

从new xx()和new xx的区别中整理JS中操作符的优先级

问题

最近在工作中写日期格式化时,遇到一个问题,先来看下面的代码:

// 写法一
new Date().toISOString

// 写法二
new Date.toISOString;

执行如下:

猜测是优先级的问题然后在MDN找到了答案,它们确实是两个不同的优先级,如下图:

以上,方式一中的 . 优先级最高,但其左边需要先求值,因而先执行new Date()得到实例,再返回实例上的toISOString属性;而方式二中的 . 优先级也是最高,但其左边不用求值,因而可以先执行Date.toISOString得到toISOString值(Date上不存在该属性因此该值为undefined),再尝试进行new toISOString操作时报错发生。

优先级

我印象中的运算符只有四十几个没想到在MDN里面找到的有六十几个。说实话上面的运算符以前真没注意过趁着空闲我决定将这些运算符整理下整理后总体分为下面的五大类

一级运算符

大部分是一元操作符。

运算符 类型 说明
( … ) 分组 优先级最高的运算符
… . … 成员访问 静态访问
[] 需计算的成员访问 动态访问
new xx() new带参数列表 实例化
() 函数调用 函数调用
?. 可选链Optional chaining a?.b类似于a === null || a === void 0 ? void 0 : a.b;
new … new无参数列表 实例化
… ++ 后置递增 先返回再+1例如 let a = 1; const b = a++; // b: 1 a: 2。比较常见的是在for循环中进行后置递增。
… -- 后置递减 同上
! … 逻辑非 (!)
~ … 按位非 (~)
+ … 一元加法 (+) 可用于把字符串转换为数值,例如+'1'将得到1
- … 一元减法 (-) 同上
++ … 前置递增 与后置递增不同,先执行+1再返回
-- … 前置递减 同上
typeof … typeof 返回值只有这几个string | number | boolean | undefined | null | function | object
void … void 比较常见的是使用void 0代替undefined因为在以前undefined是可以作为变量名使用的。
delete … delete 删除对象的属性
await … await 等待某个promise执行成功

算符运算符

运算符 类型 说明
… ** … 幂 (**)
… * … 乘法 (*)
… / … 除法 (/)
… % … 取余 (%)
… + … 加法 (+)
… - … 减法 (-)
… << … 按位左移 (<<) 通常用于二进制数据的移位, 例如:(4)<<1 将得到8。过程:十进制4转换为二进制100, 左移一位得到1000,再转换为十进制即为8
… >> … 按位右移 (>>) 同上
… >>> … 无符号右移 (>>>) 同上
… < … 小于 (<) 对于数值,比较大小
… <= … 小于等于 (<=)
… > … 大于 (>)
… >= … 大于等于 (>=)

比较运算符

运算符 类型 说明
… in … in 判断某个属性是否存在于对象上,会顺着原型链进行查找,可以用Object.prototype.hasOwnProperty.call(obj, 'xx')进行检测自身的属性是否存在。
… instanceof … instanceof 判断右边的对象,是否在左边对象的原型链上。
… == … 相等 (==) 左右两边的值可能会先做隐式转换,再进行比较,例如: '1' == 1 //true
… != … 不相等 (!=) 同上
… === … 一致/严格相等 (===) 左右两边的值不做隐式转换,直接比较,例如:'1' === 1 // false
… !== … 不一致/严格不相等 (!==) 同上

布尔运算符

运算符 类型 说明
… & … 按位与 (&) 常用于对二进制数值进行操作
… ^ … 按位异或 (^)
… | … 按位或 (|)
… && … 逻辑与 (&&)
… || … 逻辑或 (
… ?? … 空值合并 (??) 当左边的值不为undefined或null时返回左边否则返回右边 具体代码可能是这样的\n: a !== null && a !== void 0 ? a : b;

赋值运算符

运算符 类型 说明
… ? … : … 条件(三元)运算符 可以在简单场景中代替if/else使用不过自从出了??运算符,这个运算符用的比较少
… = … 赋值
… += …
… -= …
… **= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
= …
… &&= …
= …
… ??= …
… , … 逗号 / 序列 优先级最低的运算符,由于其会返回最后一个值,在某些简短操作中也会用到,例如:const map = items.reduce((m, i) => (m[i.id]=i,m), {})

结语

优先级的重要性不言而喻,往后还是要多多温习。