空值合并运算符‘??’
章节目录
上一篇:《逻辑运算符》
[下一篇:《在肝》]
空值合并运算符属于
JavaScript
逻辑运算符的一种,但又不属于传统的逻辑运算符,因此单独一篇文章进行介绍。
空值合并运算符是
JavaScript
的新特性
空值合并运算符
??
(
nullish coalescing operator
)主要针对
null
和
undefined
,本文统称值为
null
或
undefined
的变量、表达式为‘未定义的’,其他变量和表达式统称‘已定义的’。
语法
let result = exp1 ?? exp2;
以上代码的执行结果是:
- 如果表达式
exp1
是‘已定义的’,返回exp1
的结果; - 如果表达式
exp1
是‘未定义的’,返回exp2
的结果;
实际上
??
只有四种情况:
let v1 =null?? exp;//返回explet v2 =undefined?? exp;//返回explet v3 = exp ??...;//返回exp,exp非 null值或undefined
链式空值合并表达式
和其他逻辑运算符一样,
??
同样可以成链式的将多个表达式串联起来。
串联起来的
??
可以从一系列的表达式中返回第一个‘已定义的’(非
null/undefined
)表达式
举个栗子:
let result = first ?? second ?? third ??'undefined';
以上代码中,如果
first
、
second
、
third
都是空值或未定义值,将返回字符串
'undefined'
。
和三目运算符的对比
在《if else 和三目运算符》中介绍的三目运算符和
??
有相似的地方,但完全不同。
相比三目运算符,
??
在处理
null
和
undefined
情况时更为简洁。
举个栗子:
let r1 = exp1 ?? exp2;//(1)let r2 =(exp1 !==null&& exp1 !==undefined)? exp1 : exp2;//(2)let r3 = exp1 !=null? exp1 : exp2;//(3)let r4 = exp1 !=undefined? exp1 : exp2;//(4)
代码解读:
- 以上代码中第
(2)
行比较容易理解,首先!==
是===
的非形式,采用严格比较,不发生任何类型转换。所以需要分别判断exp
和null
、undefined
的相等性,如果exp
即不等于null
,又不等于undefined
,说明它是‘已定义’的,返回exp
本身,否则返回exp2
; (3)(4)
两行需要一起解读,首先在JavaScript
中null==undefined
是成立的,所以exp1 != null
和exp1 != undefined
是等价的,此外,null
和undefined
参与==
和!=
比较时不发生任何类型转换,所以exp1
只有在是null
或undefined
的情况下,才会返回exp2
。
以上解读特别的绕,所以在编程过程中,专符专用是非常重要的,炫技一时爽,失误火葬场也就是这么来的。
在处理null和undefined的比较运算时,切记,null和undefined参与
==
和
!=
比较时不发生类型转换,同时
undefined == null
成立!
和||对比
||
运算符和
??
运算符在链式使用方法中有相同的地方,例如:
let first =null;let secon =null;let third ="Beautiful Girl";let r1 = first ?? secon ?? third ??'undefined';//(1)let r2 = first || secon || thrid ||'undefined';//(2)
上述代码中,
(1)(2)
两行的作用是完全相同的,但是相对于共同点,二者的区别更大。
从定义上:
||
返回表达式中的第一个真值;??
返回表达式中的第一个已定义值;
二者的区别就在于真值和已定义值的区别上:
||
无法区分0
、false
、""
和null/undefined
,对于||
而言,它们都是一样的。??
可以区分null/undefined
和其他值的区别。
所以,在处理代码时,分真假用
||
,分有无用
??
。
由于
??
是
JavaScript
新引入的特性,所以相较于
||
,可以表达更细粒度的比较,我想这也正是
??
存在的理由。
??优先级
??
的优先级和
||
一样都是
4
,这意味着
??
运算执行在大多数运算(如
+
、
-
)之后,所以在大部分情况下都需要加上括号。
举个栗子:
let a =null;//nulllet b;//undefinedlet r1 = a ??10+ b ??9;//(1)NaNlet r2 =(a ??10)+(b ??9);//(2)19
代码
(1)(2)
有截然不同的结果,这就是运算符优先级引起的。
同样的在和其他运算符混合运算时,同样需要时刻注意,如果可以的话,加括号是个万能的解法。
总结
??
运算符可以从一系列的表达式中选出第一个“已定义的”表达式;??
常用于为可能为null/undefined
的变量赋默认值;??
运算符优先级较低,通常都需要加上括号;
课后作业
- 分别使用
!=
和!==
实现??
的功能。
章节目录
上一篇:《逻辑运算符》
[下一篇:《在肝》]
版权归原作者 @魏大大(⑉°з°)-♡ 所有, 如有侵权,请联系我们删除。