Skip to content
This repository was archived by the owner on Jan 25, 2022. It is now read-only.

Commit 43b52dd

Browse files
author
Dustin Savery
committed
[fix] fixing spec inconsistencies
1 parent b5cb08d commit 43b52dd

File tree

1 file changed

+10
-34
lines changed

1 file changed

+10
-34
lines changed

README.md

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Current Stage:
77
## Authors
88
* Claude Pache (@claudepache)
99
* Gabriel Isenberg (@the_gisenberg)
10+
* Dustin Savery (@dustinsavery)
1011

1112
## Overview and motivation
1213
When looking for a property value that's deep in a tree-like structure, one often has to check whether intermediate nodes exist:
@@ -29,19 +30,6 @@ var street = user.address?.street
2930
var fooValue = myForm.querySelector('input[name=foo]')?.value
3031
```
3132
32-
The call variant of Optional Chaining is useful for dealing with interfaces that have optional methods:
33-
34-
```js
35-
iterator.return?.() // manually close an iterator
36-
```
37-
or with methods not universally implemented:
38-
```js
39-
if (myForm.checkValidity?.() === false) { // skip the test in older web browsers
40-
// form validation fails
41-
return;
42-
}
43-
```
44-
4533
## Prior Art
4634
The following languages implement the operator with the same general semantics as this proposal (i.e., 1) guarding against a null base value, and 2) short-circuiting application to the whole chain):
4735
* C#: [Null-conditional operator](https://msdn.microsoft.com/en-us/library/dn986595.aspx) — null-conditional member access or index, in read access.
@@ -58,7 +46,6 @@ The Optional Chaining operator is spelled `?.`. It may appear in three positions
5846
```javascript
5947
obj?.prop // optional static property access
6048
obj?.[expr] // optional dynamic property access
61-
func?.(...args) // optional function or method call
6249
```
6350
6451
### Notes
@@ -79,11 +66,7 @@ a == null ? undefined : a[x]
7966

8067
a?.b()       // undefined if `a` is null/undefined
8168
a == null ? undefined : a.b() // throws a TypeError if `a.b` is not a function
82-
                            // otherwise, evaluates to `a.b()`
83-
84-
a?.()       // undefined if `a` is null/undefined
85-
a == null ? undefined : a() // throws a TypeError if `a` is neither null/undefined, nor a function
86-
            // invokes the function `a` otherwise
69+
// otherwise, evaluates to `a.b()`
8770
```
8871
8972
### Short-circuiting
@@ -116,9 +99,9 @@ Let’s call *Optional Chain* an Optional Chaining operator followed by a chain
11699
An Optional Chain may be followed by another Optional Chain.
117100
118101
```js
119-
a?.b[3].c?.(x).d
120-
a == null ? undefined : a.b[3].c == null ? undefined : a.b[3].c(x).d
121-
// (as always, except that `a` and `a.b[3].c` are evaluated only once)
102+
a?.b?.['foo'].c(x).d
103+
a == null ? undefined : a.b['foo'] == null ? undefined : a.b['foo'].c(x).d
104+
// (as always, except that `a` and `a.b['foo']` are evaluated only once)
122105
```
123106
124107
### Edge case: grouping
@@ -134,19 +117,12 @@ That follows from the design choice of specifying the scope of short-circuiting
134117
135118
Note that, whatever the semantics are, there is no practical reason to use parentheses in that position anyway.
136119
137-
### Optional deletion
138-
139-
Because the `delete` operator is very liberal in what it accepts, we have that feature for free:
140-
```js
141-
delete a?.b
142-
// delete (a == null ? undefined : a.b) // that *would* work if `? :` could return a Reference...
143-
a == null ? undefined : delete a.b // this is what we get, really
144-
```
145-
146120
## Not supported
147121
148122
Although they could be included for completeness, the following are not supported due to lack of real-world use cases or other compelling reasons; see [Issue # 22](https://github.com/tc39/proposal-optional-chaining/issues/22) and [Issue #54](https://github.com/tc39/proposal-optional-chaining/issues/54) for discussion:
149123
124+
* optional function execution: `a?.()`
125+
* optional deletion: `delete a?.b`
150126
* optional construction: `new a?.()`
151127
* optional template literal: ``a?.`{b}` ``
152128
* constructor or template literals in/after an Optional Chain: `new a?.b()`, ``a?.b`{c}` ``
@@ -165,16 +141,16 @@ All the above cases will be forbidden by the grammar or by static semantics so t
165141
<dl>
166142
167143
168-
<dt>obj?.[expr] and func?.(arg) look ugly. Why not use obj?[expr] and func?(arg) as does &lt;language X>?
144+
<dt>obj?.[expr] looks ugly. Why not use obj?[expr] as does &lt;language X>?
169145
170146
<dd>
171147
172-
We don’t use the `obj?[expr]` and `func?(arg)` syntax, because of the difficulty for the parser to efficiently distinguish those forms from the conditional operator, e.g., `obj?[expr].filter(fun):0` and `func?(x - 2) + 3 :1`.
148+
We don’t use the `obj?[expr]` syntax, because of the difficulty for the parser to efficiently distinguish those forms from the conditional operator, e.g., `obj?[expr].filter(fun):0`.
173149
174150
Alternative syntaxes for those two cases each have their own flaws; and deciding which one looks the least bad is mostly a question of personal taste. Here is how we made our choice:
175151
176152
* pick the best syntax for the `obj?.prop` case, which is expected to occur most often;
177-
* extend the use of the recognisable `?.` sequence of characters to other cases: `obj?.[expr]`, `func?.(arg)`.
153+
* extend the use of the recognisable `?.` sequence of characters to other cases: `obj?.[expr]`.
178154
179155
As for &lt;language X>, it has different syntactical constraints than JavaScript because of &lt;some construct not supported by X or working differently in X>.
180156

0 commit comments

Comments
 (0)