Skip to content

Commit 6f21f12

Browse files
authored
Update article.md
1 parent caebe7c commit 6f21f12

File tree

1 file changed

+27
-28
lines changed
  • 1-js/04-object-basics/07-optional-chaining

1 file changed

+27
-28
lines changed

1-js/04-object-basics/07-optional-chaining/article.md

+27-28
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ alert(user.address.street); // Error!
2020
或者,在 Web 开发中,我们想获取页面上某个元素的信息,但它可能不存在:
2121

2222
```js run
23-
// querySelector(...) 结果为 null 时报错
23+
// 如果 querySelector(...) 的结果为 null,则会报错
2424
let html = document.querySelector('.my-element').innerHTML;
2525
```
2626

27-
在这门语言(JavaScript)出现 `?.` 前,`&&` 运算符常被用来解决这个问题。
27+
JavaScript 这门语言中出现 `?.` 前,`&&` 运算符常被用来解决这个问题。
2828

2929
例如:
3030

@@ -34,16 +34,15 @@ let user = {}; // user 没有 address
3434
alert( user && user.address && user.address.street ); // undefined(不报错)
3535
```
3636

37-
依次对整条路径上的属性(使用与运算)进行判断,以确保所有节点是存在的,但这代码显得累赘
37+
依次对整条路径上的属性使用与运算进行判断,以确保所有节点是存在的,但是写起来很麻烦
3838

3939
## 可选链
4040

41-
如果可选链 `?.` 前一部分是 `undefined` 或者 `null`,它会停止运算并返回 `undefined`
41+
如果可选链 `?.` 前面部分是 `undefined` 或者 `null`,它会停止运算并返回 `undefined`
4242

43-
为了简明起见,在本文接下来的内容中,我们会说如果一个属性既不是 `null` 也不是 `undefined`,那么它就“存在”。
43+
**为了简明起见,在本文接下来的内容中,我们会说如果一个属性既不是 `null` 也不是 `undefined`,那么它就“存在”。**
4444

45-
46-
一种安全访问 `user.address.street` 的方式:
45+
下面这是一种安全地访问 `user.address.street` 的方式:
4746

4847
```js run
4948
let user = {}; // user 没有 address
@@ -57,21 +56,21 @@ alert( user?.address?.street ); // undefined (不报错)
5756
let user = null;
5857

5958
alert( user?.address ); // undefined
60-
6159
alert( user?.address.street ); // undefined
62-
alert( user?.address.street.anything ); // undefined
6360
```
6461
65-
请注意:`?.` 语法恰好会在它所处的位置起作用,仅此而已,不会对后面起作用。
62+
请注意:`?.` 语法使其前面的值成为可选值,但不会对其后面的起作用。
63+
64+
在上面的例子中,`user?.` 只允许 `user``null/undefined`
6665
67-
在最后两行里,运算立即在 `user?.` 后面停止,不会继续访问后面的属性。但如果 `user` 确实存在,那么后面的中间属性,如 `user.address`,就必须存在(才不会报错)
66+
另一方面,如果 `user` 存在,那么它必须具有 `user.address` 属性,否则 `user?.address.street` 在第二个点符号处会报错
6867
6968
```warn header="不要过度使用可选链"
70-
我们应该只将 `?.` 使用在属性(对象)可以不存在的地方
69+
我们应该只将 `?.` 使用在一些东西可以不存在的地方
7170

72-
例如,如果根据上面讨论的代码逻辑`user` 对象必须存在,但 `address` 是可选的,那么 `user.address?.street` 会更好。
71+
例如,如果根据我们的代码逻辑`user` 对象必须存在,但 `address` 是可选的,那么 `user.address?.street` 会更好。
7372

74-
所以,如果 `user` 恰巧因为失误变为 undefined,我们会知道并修复这个失误。相反,代码中的 error 在不恰当的地方被消除了,这会导致调试更加困难。
73+
所以,如果 `user` 恰巧因为失误变为 undefined,我们会知道并修复这个失误。否则,代码中的 error 在不恰当的地方被消除了,这会导致调试更加困难。
7574
```
7675
7776
````warn header="`?.` 前的变量必须已声明"
@@ -81,12 +80,12 @@ alert( user?.address.street.anything ); // undefined
8180
// ReferenceError: user is not defined
8281
user?.address;
8382
```
84-
可选链只会去检查 `null/undefined`,不会干扰任何其他语言机制
83+
`?.` 前的变量必须已通过 `let/const/var user` 进行声明。可选链仅适用于已声明的变量
8584
````
8685

8786
## 短路效应
8887

89-
正如之前所说,如果 `?.` 左边部分不存在,它就立即停止运算(“短路效应”)。
88+
正如前面所说的,如果 `?.` 左边部分不存在,就会立即停止运算(“短路效应”)。
9089

9190
所以,如果后面有任何函数调用或者副作用,它们均不会执行:
9291

@@ -101,11 +100,11 @@ alert(x); // 0,值没有增加
101100

102101
## 其它情况:?.(),?.[]
103102

104-
可选链 `?.` 不是一个运算符,而是一个特殊的语法结构。它还可以与函数调用和方括号一起使用
103+
可选链 `?.` 不是一个运算符,而是一个特殊的语法结构。它还可以与函数和方括号一起使用
105104

106-
例如, `?.()` 来调用一个不存在的函数
105+
例如, `?.()` 用于调用一个可能不存在的函数
107106

108-
在下面代码里,有些用户含有 `admin` 方法,而有些没有:
107+
在下面这段代码中,有些用户具有 `admin` 方法,而有些没有:
109108

110109
```js run
111110
let user1 = {
@@ -122,11 +121,11 @@ user2.admin?.();
122121
*/!*
123122
```
124123

125-
在这两行代码里,我们首先用点 `.` 来获取 `admin` 属性,因为用户对象一定存在,直接读取很安全
124+
在这两行代码中,我们首先使用点符号 `.` 来获取 `admin` 属性,因为用户对象一定存在,因此可以安全地读取它
126125

127-
然后 `?.()` 会检查它的左边:如果 admin 函数存在,那么就调用运行(对于 `user1`)。否则(对于 `user2`)运算停止,没有错误。
126+
然后 `?.()` 会检查它左边的部分:如果 admin 函数存在,那么就调用运行它(对于 `user1`)。否则(对于 `user2`)运算停止,没有错误。
128127

129-
如果我们想用方括号 `[]` 而不是点 `.` 来访问属性,语法 `?.[]` 也能用。跟前面的例子类似,它允许从一个可能不存在的对象上安全地读取属性。
128+
如果我们想使用方括号 `[]` 而不是点符号 `.` 来访问属性,语法 `?.[]` 也可以使用。跟前面的例子类似,它允许从一个可能不存在的对象上安全地读取属性。
130129

131130
```js run
132131
let user1 = {
@@ -149,27 +148,27 @@ alert( user1?.[key]?.something?.not?.existing); // undefined
149148
delete user?.name; // 如果 user 存在,则删除 user.name
150149
```
151150

152-
```warn header="我们可以使用 `?.` 来安全地读取或者删除,但不能写入"
151+
```warn header="我们可以使用 `?.` 来安全地读取或删除,但不能写入"
153152
可选链 `?.` 不能用在赋值语句的左侧:
154153
155154
```js run
156-
// 下面代码的想法是要写入 user.name,如果 user 存在的话
155+
// 下面这段代码的想法是要写入 user.name,如果 user 存在的话
157156

158-
user?.name = "John"; // Error, 不起作用
157+
user?.name = "John"; // Error不起作用
159158
// because it evaluates to undefined = "John"
160159
```
161160
162161
## 总结
163162
164-
`?.` 语法有三种形式:
163+
可选链 `?.` 语法有三种形式:
165164
166165
1. `obj?.prop` —— 如果 `obj` 存在则返回 `obj.prop`,否则返回 `undefined`
167166
2. `obj?.[prop]` —— 如果 `obj` 存在则返回 `obj[prop]`,否则返回 `undefined`
168167
3. `obj?.method()` —— 如果 `obj` 存在则调用 `obj.method()`,否则返回 `undefined`
169168
170-
如我们所见,这些语法形式用起来都很简单直接。`?.` 检查左边部分是否为 `null/undefined`,如果不是则继续运算。
169+
正如我们所看到的,这些语法形式用起来都很简单直接。`?.` 检查左边部分是否为 `null/undefined`,如果不是则继续运算。
171170
172-
`?.` 链可以安全地访问嵌套属性
171+
`?.` 链使我们能够安全地访问嵌套属性
173172
174173
但是,我们应该谨慎地使用 `?.`,仅在当左边部分不存在也没问题的情况下使用为宜。
175174

0 commit comments

Comments
 (0)