1.三目运算?//if逻辑判断if(x>y){z=100}else{z=200}//简化三目运算ifz=x>y?100:200这个没啥好说的,很常见,不知道的赶紧去补吧~2.可选链算子?.letdemo={name:'前端小九',age:20}console.log('nickname',demo.nickName.toString())执行上面的代码,会得到如下错误:nickName,会得到undefined,undefined没有toString()方法,所以报错。也就是说,当你要访问一个对象的属性或者调用一个对象的方法时,如果对象的值为undefined或者null,那么语句执行就会报错,例如://Error:为null有push方法letarr=nullarr.push(1)//错误:obj中不存在c属性,所以obj.c的值为undefined,//然后访问c中的d属性(undefined)不行letobj={a:1,b:2}console.log(obj.c.d)以前我们的解决方法是在做之前加一层判断确保访问的对象不是undefined或者null后续操作。具体代码如下:letdemo={name:'FrontendXiaojiu',age:20}//确保demo.nickName不为null/undefined//我们调用nickName.toString()方法if(demo.nickName){console.log('nickname',demo.nickName.toString())}上面的代码虽然解决了问题,但是写起来过于繁琐,不够优雅,所以新版JS增加了一个可选的链式运算符简化流程。上面的代码用可选的链运算符简化如下letdemo={name:'FrontendXiaojiu',age:20}console.log('nickname',demo.nickName?.toString())so?。optionalchain操作符的作用是如果demo对象的nickName属性的值不为null或undefined则调用其toString()方法,不存在则不调用。实际效果等同于上面的if判断。当可选链算子嵌套较深时,优势更加明显。一点都不简单。例如看下面的代码:letdemo={setp1:{name:'Step1',step2:{name:'Step2'}}}//如果我们要访问[Step2]的name属性,也就是demo.step1.step2.name//为了保证安全,我们以前可能要写如下代码if(demo&&demo.step1&&demo.step1.step2&&demo.step1.step2.name){demo.step1.step2.name.toString()}//使用可选链demo?.step1?.step2?.name?.toString()3.空值合并运算符??这是一个逻辑运算符,与||非常相似运算符,但它们并不等价。具体区别如下leta=0letb=''letc=nullletd=undefinedletx=a??100//x等于0让y=b??100//y等于''让z=c??100//z等于100让k=d??100//k等于100让o=a||100//o等于100letp=b||100//p等于100letq=c||100//q等于100letr=d||100//r等于100??当表达式的值为undefined或null时,返回右边的值。||只要运算符左侧的表达式计算结果为假,就会返回右侧的值。左边的表达式会自动做布尔运算,因为0和空字符串''做布尔运算,其值为false,所以o和p的值等于100。从上面的比较可以发现那??运算符是为了更准确的判断空值。只有null和undefined会判断为空值,0和''不会判断为空值。4.空值赋值运算符??=只有当??=左边的值为null或undefined时,右边变量的值才会赋给左边的变量,其他的值都一样不会被分配。在某些场景下,可以省略很多代码。leta=nullletb=undefinedletc=100letd=200//因为a的值为null,所以c的值会赋给a,所以最后a=100a??=c//因为b的值为undefined,所以d的值会赋值给b,所以最后b=200b??=d
