JavaScript 基础
Document
运算符
深入数据和类型
函数进阶
原型、继承
类
浏览器存储
Web API
事件
错误处理
异步编程
网络请求
模块
练习
实例
工具与规范
软件架构模式
设计模式
可选链
可选链 ?.
可以让我们安全地访问对象的属性,即使中间的属性不存在,也不会出现错误。
不存在属性的问题
当访问对象的内部对象的属性时,如果内部对象未定义,则访问其属性时会出错,因此此时等同于访问一个 undefined
中的属性。
$$jsdemo$$
$$edit$$
let mingren = {
name: "鸣人",
wife: {
name: "雏田",
},
}
let kenan = {
name: "柯南",
}
console.log(mingren.wife.name) // 雏田
// Uncaught TypeError: Cannot read properties of undefined (reading 'name')
// 因为 kenan.wife == undefined
// 等同于 undefined.name
console.log(kenan.wife.name)
当然也可以事先用 if
去判断,不过略显累赘。
$$jsdemo$$
$$edit$$
let mingren = {
name: "鸣人",
wife: {
name: "雏田",
},
}
let kenan = {
name: "柯南",
}
if (mingren.wife) {
console.log(mingren.wife.name)
}
if (kenan.wife) {
console.log(kenan.wife.name)
}
特别是层级很深的时候。
$$jsdemo$$
$$edit$$
let mingren = {
name: "鸣人",
wife: {
name: "雏田",
brother: {
name: "宁次",
},
},
}
// 恐怖的多层级嵌套
if (mingren.wife) {
if (mingren.wife.brother) {
console.log(mingren.wife.brother.name)
}
}
此时我们更期望任一层级中的对象不存在时就返回 undefined
,而不是出现错误。
可选链
如果可选链 ?.
前面的值为 undefined
或者 null
,它会停止运算并返回 undefined
。
$$jsdemo$$
$$edit$$
let mingren = {
name: "鸣人",
wife: {
name: "雏田",
brother: {
name: "宁次",
},
},
}
let kenan = null
console.log(mingren?.wife?.brother?.name) // 宁次
console.log(kenan?.wife?.name) // undefined,kenan 不存在
console.log(mingren?.brother?.name) // undefined, mingren.brother 不存在
$$warning
可选链不能用在赋值语句的左侧。
$$
$$jsdemo$$
$$edit$$
let mingren = {
name: "鸣人",
}
mingren?.friend = "小樱" // Uncaught SyntaxError: Invalid left-hand side in assignment
console.log(mingren.friend)
其他形式
method?.()
如果 method
存在则执行 method()
,否则返回 undefined
。
$$edit$$
$$jsdemo$$
let mingren = {
name: "鸣人",
sayHello() {
alert("你好~")
},
}
let kenan = {
name: "柯南",
}
mingren.sayHello?.() // 你好
kenan.sayHello?.() // 没有执行
obj?.[]
如果 obj
存在则返回 obj[prop]
,否则返回 undefined
。
$$edit$$
$$jsdemo$$
let mingren = {
name: "鸣人",
friends: ["小樱", "佐助"],
}
let kenan = {
name: "柯南",
}
alert(mingren.friends?.[0]) // 小樱
alert(kenan.friends?.[0]) // undefined
练习
- 现某学术期刊收到上传的论文数据,根据以下标准展示。
- 存在年龄且大于等于 18 则显示,否则显示未知。
- 存在姓名则显示,否则显示为匿名。
- 存在发布时间则显示,否则显示未知。
// 论文数据
const articles = [
{
title: "蟹黄堡的营销发展。",
author: {
name: "蟹老板",
age: 34,
},
info: {
publishTime: "2022年7月18日",
},
},
{
title: "海洋生物与陆地生物的差异。",
},
{
title: "海绵宝宝存在的意义。",
author: {
name: "海绵宝宝",
age: 18,
},
},
{
title: "派大星的私密生活。",
author: {
name: "派大星",
age: 16,
},
},
{
title: "蟹黄堡配方调研。",
author: {
name: "痞老板",
age: 32,
},
info: {
publishTime: null,
},
},
{
title: "如何在海底培育植物。",
author: {
age: 20,
},
info: {
publishTime: "2022年10月20日",
},
},
]
$$demo <button onclick="show()">显示论文</button> <script> // 论文数据 const articles = [ { title: "蟹黄堡的营销发展。", author: { name: "蟹老板", age: 34, }, info: { publishTime: "2022年7月18日", }, }, { title: "海洋生物与陆地生物的差异。", }, { title: "海绵宝宝存在的意义。", author: { name: "海绵宝宝", age: 18, }, }, { title: "派大星的私密生活。", author: { name: "派大星", age: 16, }, }, { title: "蟹黄堡配方调研。", author: { name: "痞老板", age: 32, }, info: { publishTime: null, }, }, { title: "如何在海底培育植物。", author: { age: 20, }, info: { publishTime: "2022年10月20日", }, }, ]
function show() {
for (const article of articles) {
let infoList = [`选题:${article.title}`]
if (article.author?.age && article.author?.age >= 18) {
infoList.push(`年龄:${article.author.age}`)
} else {
infoList.push(`年龄:未知`)
}
infoList.push(`署名:${article.author?.name ?? "匿名"} `)
infoList.push(`发布时间:${article.info?.publishTime ?? "未知"} `)
alert(infoList.join("\n"))
}
}
</script>
$$
$$answer
$$jsdemo$$
$$edit$$
// 论文数据
const articles = [
{
title: "蟹黄堡的营销发展。",
author: {
name: "蟹老板",
age: 34,
},
info: {
publishTime: "2022年7月18日",
},
},
{
title: "海洋生物与陆地生物的差异。",
},
{
title: "海绵宝宝存在的意义。",
author: {
name: "海绵宝宝",
age: 18,
},
},
{
title: "派大星的私密生活。",
author: {
name: "派大星",
age: 16,
},
},
{
title: "蟹黄堡配方调研。",
author: {
name: "痞老板",
age: 32,
},
info: {
publishTime: null,
},
},
{
title: "如何在海底培育植物。",
author: {
age: 20,
},
info: {
publishTime: "2022年10月20日",
},
},
]
for (const article of articles) {
let infoList = [`选题:${article.title}`]
if (article.author?.age && article.author?.age >= 18) {
infoList.push(`年龄:${article.author.age}`)
} else {
infoList.push(`年龄:未知`)
}
infoList.push(`署名:${article.author?.name ?? "匿名"} `)
infoList.push(`发布时间:${article.info?.publishTime ?? "未知"} `)
alert(infoList.join("\n"))
}
$$