JS的链判断符有几种写法,有哪些用法?
你好,我是沐爸,欢迎点赞、收藏、评论和关注。
在 ES6 之前如何判断一个对象深层嵌套的属性?ES6 的链判断符又是怎么简化操作的呢?它有几种写法?带着这三个问题,我们一起看一看。
ES6 之前
在 ES6 之前的 JS 中,如果读取对象内部的某个属性,往往需要判断一下,属性的上层对象是否存在。比如,读取message.body.user.firstName
这个属性,安全的写法是写成下面这样。
// 错误的写法
const firstName = message.body.user.firstName || 'default';// 正确的写法
const firstName = (message&& message.body&& message.body.user&& message.body.user.firstName) || 'default';
三元运算符?:
也常用于判断对象是否存在。
const firstName = user ? user.firstName : 'default'
以上两种判断其实都有局限性,它们在判断对象的最后一层属性,只要属性值是假(0,false,null,“”,undefined),结果都会是默认值,这在一些情况下并不符合要求。
ES6 链判断符 ?.
ES6 新增了链判断符,会从左到右评估其表达式,如果某个属性的值为 null 或 undefined,则表达式短路返回 undefined,而不是抛出错误。这个操作符允许你安全地读取深层嵌套对象属性的值,而无需显式地验证每一层是否存在,使用非常方便。注意,短路逻辑的特点是,只要不满足条件,就不再往下执行。
链判断运算符 ?.
有三种写法
obj?.prop
// 对象属性是否存在obj?.[expr]
// 同上func?.(...args)
// 函数或对象方法是否存在
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()
常见用法示例如下:
示例一:访问深层嵌套属性
假设我们有一个包含多层嵌套对象的用户数据,我们想要安全地访问用户的城市信息:const user = {id: 1,name: '张三',address: {street: '长安街2024号',city: '北京'}
}// 使用链判断符
const city = user?.address?.city
console.log(city) // 北京 // 如果 address 属性不存在
const user2 = { id: 2,name: '李四'
}
const city2 = user2?.address?.city
console.log(city2) // undefined
示例二:调用可能不存在的方法
在尝试调用一个对象的方法之前,我们可以使用链判断符来检查该方法是否存在:const obj = {greet: function() {console.log('Hello!')}
}// 使用链判断符调用方法
obj?.greet?.(); // 输出: Hello!// 如果方法不存在
obj?.say?.() // 不会抛出错误,只是什么也不做
示例三:结合空值合并操作符使用
链判断符经常与空值合并操作符(` ??` )一起使用,以在属性不存在时提供一个默认值:const user2 = {id: 2,name: '李四'
}// 使用可选链和空值合并操作符
const city = user?.address?.city ?? 'Unknown City'
console.log(city) // Unknown City
示例四:处理数组和函数返回值
链判断符也可以用于处理数组和函数的返回值,当你不确定它们是否为` null` 或` undefined` 时:const arr = [1, 2, 3, { name: 'Item 4' }]
const item3 = arr[3]?.name
console.log(item3) // Item 4// 如果索引超出范围
const item10 = arr[10]?.name
console.log(item10) // undefined// 函数返回值示例
function getUser() {// 假设这个函数在某些情况下返回 nullreturn null
}const userName = getUser()?.name ?? 'unKnown'
console.log(userName) // unKnown
好了,分享结束,谢谢点赞,下期再见。