JavaScript - 可选链
JavaScript 中的可选链允许您访问对象的嵌套属性和方法,而无需检查每个属性是否存在。这有助于使您的代码更简洁、更易于阅读。
可选链运算符 (?.) 用于在 JavaScript 中实现可选链。它位于要访问的属性或方法之前。如果该属性或方法不存在,表达式将计算结果为 undefined,而不是抛出错误。
不存在属性的问题
让我们通过不存在属性的问题来理解 JavaScript 中可选链的必要性。
在 JavaScript 中使用对象时,您可能会遇到具有动态属性的对象。一些属性也包含对象作为值,称为嵌套对象。
如果您尝试访问父级不存在的嵌套属性,JavaScript 可能会抛出错误。
例如,
const parent = {
child: {
name: "Smith",
}
}
const name = parent.child.name;
父对象包含 'ch' 属性,而 'ch' 属性包含嵌套对象作为值。
在代码中,您访问了 'child' 嵌套对象的 'name' 属性,但 'child' 属性在父对象中不存在。因此,当您访问 undefined 属性时,JavaScript 将抛出以下错误。
Uncaught TypeError: Cannot read properties of undefined
为了解决上述问题,在 ES11 之前使用了 '&&' 运算符。
例如,
if (parent.child && parent.child.name) {
// 在这里访问 parent.child.name
}
在上面的代码中,我们首先检查 parent.child 是否存在。如果存在,则访问其 name 属性以避免错误。
您找到了解决方案,但是如果您需要从对象的第四层或第五层访问该属性怎么办?您需要使用多个 && 运算符并编写复杂的代码。
这里,可选链运算符 (?.) 应运而生,可以轻松解决不存在属性的问题。
什么是 JavaScript 中的可选链?
在 JavaScript 中,可选链运算符 (?.) 于 ECMAScript 2020 (ES2020) 中引入。它提供了访问对象属性、数组元素等的最佳方式。
可选链与用于访问对象嵌套属性的常规链非常相似。它在访问对象属性之前检查嵌套属性是否存在,以避免错误。
语法
您可以按照以下语法在 JavaScript 中使用可选链式运算符。
Obj?.prop1?.nestedprop; // 访问嵌套属性 Obj?.[expression]; // 通过表达式访问对象属性 Array?.[index]; // 访问数组元素 funcName?.(); // 执行函数
在上述语法中,如果 obj 对象存在,它将访问 prop1 属性。再次,代码检查 obj 对象中是否存在 prop1 属性,如果存在,它将访问 nestedProp 属性。否则,它将停止代码执行以避免错误。
您还可以使用表达式和可选链访问对象属性值。
可选链也可用于访问数组元素并执行函数。
返回值
如果属性不存在,可选链将返回 undefined 而不会抛出任何错误。
示例
在下面的示例中,car 对象包含 'info' 嵌套对象。info 对象包含 color 和 price 属性。
我们尝试使用可选链访问 info 对象的 price 属性,它返回 5000000。
之后,我们尝试使用可选链访问 car 对象的 engine 属性的 gears 属性。在输出中,您可以看到它返回 undefined 而不是抛出错误。
<html>
<body>
<div id = "output1">The price of the Audi Q6 is: </div>
<div id = "output2">Total gears in the Audi Q6 is: </div>
<script>
const car = {
brand: "Audi",
model: "Q6",
info: {
price: 5000000,
color: "Black",
}
}
document.getElementById("output1").innerHTML += car.info?.price;
document.getElementById("output2").innerHTML += car.engine?.gears;
</script>
</body>
</html>
输出
The price of the Audi Q6 is: 5000000 Total gears in the Audi Q6 is: undefined
函数调用中的可选链
在 JavaScript 中,你也可以在函数调用中使用可选链。如果函数未定义,它将返回 undefined。否则,代码将执行该函数。
示例
在下面的代码中,我们将可选链与对象方法结合使用。
car 对象包含 getBrand() 方法。我们在执行 getBrand() 方法时使用了可选链,该方法返回"Audi"。
此外,我们尝试使用可选链执行 car 对象的 getColor() 方法。由于 car 对象不包含 getColor() 方法,因此返回 undefined。
<html>
<body>
<div id = "output1">The brand of the car is: </div>
<div id = "output2">The color of the car is: </div>
<script>
const car = {
getBrand() {
return "Audi";
},
}
document.getElementById("output1").innerHTML += car.getBrand?.();
document.getElementById("output2").innerHTML += car.getColor?.();
</script>
</body>
</html>
输出
The brand of the car is: Audi The color of the car is: undefined
使用表达式的可选链
在使用表达式或数组元素访问对象属性时,可以使用可选链。
示例
在下面的代码中,动物对象包含 name 和 info 属性。info 属性又包含一个嵌套对象,该对象具有 legs 和 tail 属性。
我们使用可选链和表达式访问对象属性。您可以看到,即使动物对象中不存在"specs"属性,它也能打印代码而不会引发任何错误。
<html>
<body>
<div id = "output1">Total number of legs of the tiger is: </div>
<div id = "output2">The color of the tiger is: </div>
<script>
const animal = {
name: "Tiger",
info: {
legs: 4,
tail: 1,
}
}
document.getElementById("output1").innerHTML += animal.info?.["legs"];
document.getElementById("output2").innerHTML += animal.specs?.["color"];
</script>
</body>
</html>
输出
Total number of legs of the tiger is: 4 The color of the tiger is: undefined
使用"delete"运算符进行可选链式调用
JavaScript 的 delete 运算符用于删除对象属性。如果尝试删除不存在的属性,代码将抛出错误。因此,您可以将可选链运算符与 delete 运算符结合使用。
示例
在下面的代码中,我们使用 delete 运算符删除嵌套 info 对象的 legs 属性和嵌套 'specs' 对象的 tail 属性,并使用可选链访问属性。
animal 对象不包含 specs 属性。尽管如此,由于使用了可选链,代码运行时仍然没有任何错误。
<html>
<body>
<div id = "demo"> </div>
<script>
const animal = {
name: "Tiger",
info: {
legs: 4,
tail: 1,
}
}
delete animal.info?.legs;
delete animal.sepcs?.tail;
document.getElementById("demo").innerHTML =
"Updated object is: " + JSON.stringify(animal);
</script>
</body>
</html>
输出
Updated object is: {"name":"Tiger","info":{"tail":1}}
使用可选链实现短路
在 JavaScript 中,短路的含义是每当出现错误时,就停止代码的执行。您可以使用可选链访问对象的每个嵌套属性,以避免任何错误,并在出现错误时停止代码的执行。
示例
在下面的代码中,animal 对象包含 info 对象,而 info 对象又包含 leg 对象。我们使用可选链访问每个嵌套属性。因此,如果任何属性不存在,它将返回 undefined 并避免错误。
<html>
<body>
<div id = "output1">The size of the first leg is: </div>
<div id = "output2"> The size of the third leg is: </div>
<script>
const animal = {
name: "Tiger",
info: {
legs: {
first: 1.32,
second: 1.31,
},
tail: 1,
}
}
document.getElementById("output1").innerHTML += animal?.info?.legs?.first;
document.getElementById("output2").innerHTML += animal?.specs?.legs?.third;
</script>
</body>
</html>
输出
The size of the first leg is: 1.32 The size of the third leg is: undefined
空值合并运算符与可选链式调用
当任何对象属性不存在时,可选链式调用会停止代码执行并返回 undefined。如果将 JavaScript 空值合并运算符与其结合使用,则可以在对象属性不存在时返回默认值。
示例
在下面的代码中,我们尝试访问"animal"对象中"specs"对象的 color 属性。此处,"specs"在 animal 对象中不存在。因此,由于我们使用了空值合并运算符,因此返回"red"。
<html>
<body>
<div id = "output">The color of the animal is: </div>
<script>
const animal = {
name: "Tiger",
info: {
legs: 2,
tail: 1,
}
}
animal.info?.legs;
const color = animal?.spec?.color ?? "Red";
document.getElementById("output").innerHTML += color;
</script>
</body>
</html>
输出
The color of the animal is: Red
简单来说,您可以在任何需要访问动态对象的属性的地方使用可选链运算符,以避免错误。

