我们公司想做个网站,功能网站建设多少钱,分析seo做的不好的网站,网站建设百度知道在实际应用中#xff0c;如果读取对象内部 的某个属性#xff0c;往往需要判断一下#xff0c;属性的上层对象是否存在。比如#xff0c;读取message.body.user.firstName这个属性#xff0c;安全的写法是写成下下面这样#xff1a;
// 错误的写法
const firstName mes…在实际应用中如果读取对象内部 的某个属性往往需要判断一下属性的上层对象是否存在。比如读取message.body.user.firstName这个属性安全的写法是写成下下面这样
// 错误的写法
const firstName message.body.user.firstName || default// 正确的写法
const firstName (message message.body message.body.user messaage.body.user.firstName) || default上面的例子firstName属性在对象的第四层所以需要判断四次每一层是否有值。三元运算符也常用于判断对象是否存在
const fooInput myForm.querySelector(input[namefoo])
const footVal fooInput ?footInput.value : undefined
上面的例子必须先判断fooInput是否存在才能读取fooInput.value
这样层层判断非常麻烦因此ES2020引入了“链式判断运算符”---?.简化上面的写法
const firstName message?.body?.user?.firstName || default
const fooVal myForm.querySelector(input[namefoo])?.value
上面代码中使用了?.运算符直接在链式调用的时候判断左侧的对象是否为null或者undefined如果是的就不再往下运算而是返回undefined
下面是判断 对象方法是否存在如果存在就立即执行的例子
iterator.return?.()
上面的代码中iterator.return如果有定义就会调用该方法否则iterator.return直接返回undefined不再执行?.后面的部分
对于那些可能没有实现的方法这个运算符尤其有用
if(myForm.checkValidity?.()false){return
}
上面代码中老式浏览器的表单对象可能没有checkValidity()这个方法这时?.运算符就会返回undefined判断语句就变成了undefinedfalse所以就会跳过下面的代码
链式判断运算符?.有是那种写法 obj?.prop 对象属性是否存在obj?.[expr]同上 func?.(...args)函数或者对象方法是否存在
下面是obj?.[expr]用法的一个例子
let hex #C0FFEE.match(/#([A-Z])/i)?.[1];
上面代码中字符串match()方法如果没有发现匹配会返回null如果发现匹配会返回一个数组?.运算符起到了判断作用
下面?.运算符常见形式以及不实用运算符时的等价形式
a?.b
// 等同于
a null ? undefined : a.ba?.[x]
a null ? undefined :a[x]a?.b()
a null ? undefined :a.b()a?.()
a null ? undefined : a()
上面的代码 中特别注意后面两种形式 a?.b()和a?.()如果a?.b()里面的a.b有值但不是函数不可调用。那么a?.b()是会报错的。a?.()也是如此如果a不是null或undefined但也不是函数那么a?.()会报错
使用这个运算符有几个注意点
1短路机制
本质上?.运算符相当于一个短路机制只要不满足条件就不会往下执行
a?.[x]
//
a null ? undefined : a[x]
上面代码中如果a是undefined或者null那么x不会进行递增运算。也就是说链式判断运算符一旦不为真右侧的表达式就不再求值。
2括号的影响
如果属性链有圆括号链判断运算符对圆括号外部没有影响 只对圆括号内部有影响
(a?.b).c
//
(a null ? undefined : a.b).c
上面代码中?.对圆括号外部没有影响不管a对象是否存在圆括号后面的.c总是会执行。
一般来说使用?.运算符的场合不应该使用圆括号。
3报错场合
以下写法是错误的会报错
// 构造函数
new a?.()
new a?.b()// 链判断运算符的右侧有模板字符串
a?.{b}
a?.b{c}// 链判断运算符的左侧是 super
super?.()
super?.foo// 链运算符用于赋值运算符左侧
a?.b c