@@ -129,29 +129,48 @@ const firstName = (message
129129 && message .body .user .firstName ) || ' default' ;
130130```
131131
132+ 或者使用三元运算符` ?: ` ,判断一个对象是否存在。
133+
134+ ``` javascript
135+ const fooInput = myForm .querySelector (' input[name=foo]' )
136+ const fooValue = fooInput ? fooInput .value : undefined
137+ ```
138+
132139这样的层层判断非常麻烦,因此现在有一个[ 提案] ( https://github.com/tc39/proposal-optional-chaining ) ,引入了“链判断运算符”(optional chaining operator)` ?. ` ,简化上面的写法。
133140
134141``` javascript
135142const firstName = message? .body ? .user ? .firstName || ' default' ;
143+ const fooValue = myForm .querySelector (' input[name=foo]' )? .value
136144` ` `
137145
138- 上面代码有三个 ` ? .` 运算符,直接在链式调用的时候判断,左侧的对象是否为` null ` 或` undefined ` 。如果是的,就不再往下运算,而是返回` undefined ` 。
146+ 上面代码使用了 ` ? .` 运算符,直接在链式调用的时候判断,左侧的对象是否为` null ` 或` undefined ` 。如果是的,就不再往下运算,而是返回` undefined ` 。
139147
140- 链判断运算符号有三种用法 。
148+ 链判断运算符有三种用法 。
141149
142- - ` obj? .prop ` // 读取对象属性
150+ - ` obj? .prop ` // 对象属性
143151- ` obj? .[expr]` // 同上
144152- ` func? .(... args)` // 函数或对象方法的调用
145153
146- 下面是判断函数是否存在的例子 。
154+ 下面是判断对象方法是否存在,如果存在就立即执行的例子 。
147155
148156` ` ` javascript
149157iterator .return ? .()
150158` ` `
151159
152160上面代码中,` iterator .return ` 如果有定义,就会调用该方法,否则直接返回` undefined ` 。
153161
154- 下面是更多的例子。
162+ 对于那些可能没有实现的方法,这个运算符尤其有用。
163+
164+ ` ` ` javascript
165+ if (myForm .checkValidity ? .() === false ) {
166+ // 表单校验失败
167+ return ;
168+ }
169+ ` ` `
170+
171+ 上面代码中,老式浏览器的表单可能没有` checkValidity` 这个方法,这时` ? .` 运算符就会返回` undefined ` ,判断语句就变成了` undefined === false ` ,所以就会跳过下面的代码。
172+
173+ 下面是这个运算符常见的使用形式,以及不使用该运算符时的等价形式。
155174
156175` ` ` javascript
157176a? .b
@@ -171,6 +190,8 @@ a?.()
171190a == null ? undefined : a ()
172191` ` `
173192
193+ 上面代码中,特别注意后两种形式,如果` a? .b ()` 里面的` a .b ` 不是函数,不可调用,那么` a? .b ()` 是会报错的。` a? .()` 也是如此,如果` a` 不是` null ` 或` undefined ` ,但也不是函数,那么` a? .()` 会报错。
194+
174195使用这个运算符,有几个注意点。
175196
176197(1)短路机制
@@ -193,26 +214,40 @@ a == null ? undefined : delete a.b
193214
194215上面代码中,如果` a` 是` undefined ` 或` null ` ,会直接返回` undefined ` ,而不会进行` delete ` 运算。
195216
196- (3)报错场合
217+ (3)括号不改变运算顺序
197218
198- 以下写法是禁止,会报错。
219+ ` ` ` javascript
220+ (a? .b ).c
221+ // 等价于
222+ (a == null ? undefined : a .b ).c
223+ ` ` `
224+
225+ 上面代码中,` ? .` 对圆括号没有影响,不管` a` 对象是否存在,圆括号后面的` .c ` 总是会执行。
226+
227+ 一般来说,使用` ? .` 运算符的场合,不应该使用圆括号。
228+
229+ (4)报错场合
230+
231+ 以下写法是禁止的,会报错。
199232
200233` ` ` javascript
201- // 构造函数判断
234+ // 构造函数
202235new a ? .()
236+ new a ? .b ()
203237
204- // 运算符右侧是模板字符串
238+ // 链判断运算符的右侧有模板字符串
205239a? .` {b}`
206-
207- // 链判断运算符前后有构造函数或模板字符串
208- new a ? .b ()
209240a? .b ` {c}`
210241
242+ // 链判断运算符的左侧是 super
243+ super ? .()
244+ super ? .foo
245+
211246// 链运算符用于赋值运算符左侧
212247a? .b = c
213248` ` `
214249
215- (4 )右侧不得为十进制数值
250+ (5 )右侧不得为十进制数值
216251
217252为了保证兼容以前的代码,允许` foo? .3 : 0 ` 被解析成` foo ? .3 : 0 ` ,因此规定如果` ? .` 后面紧跟一个十进制数字,那么` ? .` 不再被看成是一个完整的运算符,而会按照三元运算符进行处理,也就是说,那个小数点会归属于后面的十进制数字,形成一个小数。
218253
0 commit comments