Javascript 简明教程
JavaScript - Optional Chaining
JavaScript 中的可选链允许您访问对象中的嵌套属性和方法,而不必检查每个属性的存在性。这有助于让您的代码更简练、易于阅读。
The optional chaining in JavaScript allows you to access nested properties and methods of an object without checking if each property exists. This can help to make your code more concise and easier to read.
可选链操作符(?。)用于在 JavaScript 中实现可选链。它应放置在您希望访问的属性或方法之前。如果属性或方法不存在,该表达式将会评估为 undefined,而不是引发错误。
The optional chaining operator (?.) is sued to achieve optional chaining in JavaScript. It is placed before the property or method that you want to access. If the property or method does not exist, the expression will evaluate to undefined instead of throwing an error.
The Non-existing Property Problem
我们通过非现有属性问题来了解 JavaScript 中对于可选链的需求。
Let’s understand the need for optional chaining in JavaScript via the non-existing property problem.
使用 JavaScript 中的对象时,对象中可能会有动态属性。部分属性还包含对象本身,即所谓的嵌套对象。
While working with objects in JavaScript, you may have objects with dynamic properties. Some properties also contain the object as a value, called nested objects.
如果您尝试访问不存在父项的嵌套属性,JavaScript 会引发错误。
JavaScript can throw an error if you try to access the nested property whose parent doesn’t exist.
例如,
For example,
const parent = {
child: {
name: "Smith",
}
}
const name = parent.child.name;
父对象包含 "ch" 属性,并且 "ch" 属性包含嵌套对象作为值。
The parent object contains the 'ch' property, and the 'ch' property contains the nested object as a value.
在代码中,您访问 "child" 嵌套对象的 "name" 属性,但是 "child" 属性在父对象中不存在。因此,在您访问未定义属性时,JavaScript 就会引发以下错误。
In the code, you access the 'name' property of the 'child' nested object, but the 'child' property doesn’t exist in the parent object. So, JavaScript will throw the below error as you access the undefined property.
Uncaught TypeError: Cannot read properties of undefined
为了解决上面的问题,ES11 之前使用 "&&" 操作符。
To solve the above problem, the '&&' operator was used before ES11.
例如,
For example,
if (parent.child && parent.child.name) {
// access parent.child.name here
}
在上面的代码中,我们首先检查是否存在 parent.child。如果是,我们访问其 name 属性以避免错误。
In the above code, we first check whether the parent.child exists. If yes, we access its name property to avoid the error.
您获得了这个解决方案,但是如果需要从对象的第 4 或第 5 层访问该属性怎么办?您需要使用多个 && 操作符并编写复杂的代码。
You got the solution, but what if you need to access the property from the 4th or 5th level of the object? You need to use multiple && operators and write complex code.
此处,可选链操作符(?。)出现在画面中,以轻松解决非现有属性问题。
Here, the optional chaining operator (?.) comes into the picture to solve the non-existing property problem easily.
What is an Optional Chaining in JavaScript?
在 JavaScript 中,可选链操作符(?。)在 ECMAScript 2020(ES2020)中引入。它提供了访问对象属性、数组元素等的最佳方法。
In JavaScript, optional chining operator (?.) is introduced in ECMAScript 2020 (ES2020). It provides the best way to access object properties, array elements, etc.
可选链与用于访问对象嵌套属性的普通链非常相似。它在访问对象属性前检查嵌套属性是否存在,以避免错误。
The optional chaining is very similar to normal chaining used to access the nested properties of the object. It checks whether the nested property exists before accessing the object property to avoid the error.
Syntax
您可以遵循以下语法在 JavaScript 中使用可选链操作符。
You can follow the syntax below to use the optional chaining operator in JavaScript.
Obj?.prop1?.nestedprop; // Accessing nested properties
Obj?.[expression]; // Accessing object property via expression
Array?.[index]; // Accessing array element
funcName?.(); // Executing the funciton
-
In the above syntax, if the obj object exists, it will access the prop1 property. Again the code checks if the prop1 property exists in the obj object, it will access the nestedProp property. Otherwise, it will stop the code execution to avoid errors.
-
You can also access the object property value using the expression and optional chaining.
-
Optional chaining can also be used for accessing array elements and executing the function.
Return value
如果某个属性不存在,则可选链返回 undefined,而不会引发任何错误。
If a property does not exist, the optional chain returns undefined without throwing any error.
Example
在下面的示例中,car 对象包含 info 嵌套对象。info 对象包含 color 和 price 属性。
In the example below, the car object contains the 'info' nested object. The info object contains the color and price property.
我们尝试使用可选链访问 info 对象的 price 属性,它返回 5000000。
We try to access the price property of the info object using the optional chain, it returns 5000000.
然后,我们尝试使用可选链访问 car 对象的 engine 属性的 gears 属性。在输出中,你可以看到它返回 undefined,而不是引发错误。
After that, we try to access the gears property of the engine property of the car object using the optional chain. In the output, you can see that it returns undefined rather than throwing an error.
<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
Optional Chaining with Function Calls
在 JavaScript 中,你还可以将可选链与函数调用一起使用。如果该函数未定义,它将返回 undefined。否则,代码将执行该函数。
In JavaScript, you can also use the optional chaining with the function calls. If the function is not defined, it will return the undefined. Otherwise, the code will execute the function.
Example
在下面的代码中,我们对对象方法使用了可选链。
In the below code, we used the optional chain with object methods.
car 对象包含 getBrand() 方法。我们使用可选链执行 getBrand() 方法,该方法返回 'Audi'。
The car object contains the getBrand() method. We used the optional chain while executing the getBrand() method, which returns 'Audi'.
此外,我们尝试使用可选链执行 car 对象的 getColor() 方法。它返回 undefined,因为 car 对象不包含 getColor() 方法。
Also, we try to execute the getColor() method of the car object with an optional chain. It returns undefined as the car object doesn’t contain the getColor() method.
<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
Optional Chaining with Expression
你可以使用可选链访问对象属性时使用表达式或数组元素。
You can use the optional chain while accessing the object properties using the expression or array element.
Example
在下面的代码中,animal 对象包含name 和 info 属性。info 属性再次包含具有 legs 和 tail 属性的嵌套对象。
In the below code, the animal object contains the name and info property. The info property again contains the nested object having legs and tail properties.
我们使用可选链和表达式访问对象属性。你可以看到它在代码中打印输出,而不会引发任何错误,即使 'specs' 属性在 animal 对象中不存在也是如此。
We access the object properties using the optional chain and expression. You can see that it prints the output in the code without throwing any error, even the 'specs' property doesn’t exist in the animal object.
<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
Optional Chaining with the "delete" Operator
JavaScript delete 运算符用于删除对象属性。如果你尝试删除不存在的属性,代码将引发错误。因此,你可以将可选链运算符与 delete 运算符一起使用。
The JavaScript delete operator is used to delete the object properties. If you try to delete properties that do not exist, the code will throw an error. So, you can use the optional chain operator with the delete operator.
Example
在下面的代码中,我们使用 delete 运算符删除嵌套 info 对象的 legs 属性和 'specs' 嵌套对象的 tail 属性,并使用可选链访问属性。
In the below code, we delete the legs property of the nested info object and the tail property of the 'specs' nested object using the delete operator and access properties using the optional chain.
animal 对象不包含 specs 属性。尽管如此,由于可选链,代码仍然可以毫无错误地运行。
The animal object doesn’t contain the specs property. Still, the code runs without any error due to the optional chain.
<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}}
Short-circuiting with Optional Chaining
在 JavaScript 中,短路的意思是每当你遇到错误时,就会停止代码的执行。你可以使用可选链访问对象的每个嵌套属性,以避免任何错误并在发生错误时停止代码执行。
In JavaScript, the meaning of short-circuiting is that whenever you get an error, stop the execution of the code. You can use the optional chain for accessing each nested property of the object to avoid any error and stop the execution of the code on error.
Example
在下面的代码中,animal 对象包含 info 对象,info对象包含 legs 对象。我们使用可选链访问每个嵌套属性。因此,如果任何属性不存在,它将返回 undefined 并避免错误。
In the below code, the animal object contains the info object, and the info object contains the legs object. We use the optional chain to access each nested property. So, if any property doesn’t exist, it will return undefined and avoid errors.
<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
Nullish Coalescing Operator with Optional Chaining
当任何对象属性不存在时,可选链停止代码执行并返回 undefined。如果你将 JavaScript nullish 归并运算符与它一起使用,则当对象属性不存在时,你可以返回默认值。
When any object property doesn’t exist, the optional chain stops the code execution and returns undefined. If you use the JavaScript nullish coalescing operator with it, you can return the default value when the object property doesn’t exist.
Example
在下面的代码中,我们尝试访问 'animal' 对象的 'specs' 对象的 color 属性。这里,'specs' 在 animal 对象中不存在。因此,由于我们使用了 nullish 归并运算符,它返回 'red'。
In the below code, we try to access the color property of the 'specs' object of the 'animal' object. Here, 'specs' do not exist in the animal object. So, it returns 'red' as we used the nullish coalescing operator.
<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
简单来说,在需要访问动态对象的属性以避免错误的任何地方都可以使用可选链运算符。
In simple terms, you can use the optional chain operator wherever you need to access the properties of the dynamic object to avoid an error.