JavaScript - 可选链接



JavaScript 中的可选链接允许您访问对象的嵌套属性和方法,而无需检查每个属性是否存在。这有助于使您的代码更简洁、更易于阅读。

使用可选链接运算符 (?.) 在 JavaScript 中实现可选链接。它位于要访问的属性或方法之前。如果属性或方法不存在,则表达式的计算结果将为 undefined,而不是引发错误。

不存在的财产问题

让我们通过不存在财产问题来理解 JavaScript 中对可选链接的需求。

在 JavaScript 中使用对象时,您可能拥有具有 dynamic 属性的对象。某些属性还包含对象作为值,称为嵌套对象。

如果你尝试访问其 parent 不存在的嵌套属性,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) {
	 	// access parent.child.name here
}

在上面的代码中,我们首先检查 parent.child 是否存在。如果是,我们将访问其 name 属性以避免错误。

您得到了解决方案,但是如果您需要从对象的第 4 级或第 5 级访问该属性,该怎么办?你需要使用多个 & 运算符并编写复杂的代码。

在这里,可选的链接运算符 (?.) 出现,可以轻松解决不存在的属性问题。

什么是 JavaScript 中的可选链接?

在 JavaScript 中,可选的chining运算符(?.)在 ECMAScript 2020 (ES2020) 中引入。它提供了访问对象属性、数组元素等的最佳方式。

可选链接与用于访问对象的嵌套属性的普通链接非常相似。它会在访问 object 属性之前检查嵌套属性是否存在,以避免错误。

语法

您可以按照以下语法在 JavaScript 中使用可选的 chaining 运算符。


Obj?.prop1?.nestedprop; // Accessing nested properties
Obj?.[expression]; // Accessing object property via expression
Array?.[index]; // Accessing array element
funcName?.(); // Executing the funciton	
  • 在上面的语法中,如果 obj 对象存在,它将访问 prop1 属性。同样,代码检查 obj 对象中是否存在 prop1 属性,它将访问 nestedProp 属性。否则,它将停止代码执行以避免错误。
  • 您还可以使用表达式和可选链接来访问 object 属性值。
  • 可选的链接也可用于访问数组元素和执行函数。

返回值

如果属性不存在,则可选链返回 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。否则,代码将执行该函数。

在下面的代码中,我们使用了带有 object 方法的可选链。

car 对象包含 getBrand() 方法。我们在执行 getBrand() 方法时使用了可选链,该方法返回 'Audi'。

此外,我们尝试使用可选链执行 car 对象的 getColor() 方法。它返回 undefined,因为 car 对象不包含 getColor() 方法。


<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

可选 Chaining with Expression

在使用 expression 或 array 元素访问对象属性时,可以使用可选链。

在下面的代码中,animal 对象包含 name 和 info 属性。info 属性再次包含具有 legs 和 tail 属性的嵌套对象。

我们使用可选的 chain 和 expression 来访问对象属性。你可以看到它在代码中打印输出而没有抛出任何错误,即使 'specs' 属性在 animal 对象中不存在。


<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 运算符用于删除对象属性。如果尝试删除不存在的属性,代码将引发错误。因此,您可以将可选的 chain 运算符与 delete 运算符一起使用。

在下面的代码中,我们使用 delete 运算符删除嵌套 info 对象的 legs 属性和 'specs' 嵌套对象的 tail 属性,并使用可选链删除 access 属性。

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 对象包含 legs 对象。我们使用 optional chain 来访问每个嵌套属性。因此,如果任何属性不存在,它将返回 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

具有可选链接的 Nullish 合并运算符

当任何 object 属性不存在时,可选链将停止代码执行并返回 undefined。如果将 JavaScript nullish 合并运算符与它一起使用,则可以在 object 属性不存在时返回默认值。

在下面的代码中,我们尝试访问 'animal' 对象的 'specs' 对象的 color 属性。在这里,“specs” 在 animal 对象中不存在。因此,它返回 'red',因为我们使用了 nullish 合并运算符。


<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

简单来说,你可以在需要访问动态对象属性的任何地方使用可选的链运算符,以避免错误。