Skip to content

Commit f409905

Browse files
committed
minor fixes
1 parent ae06ca6 commit f409905

File tree

2 files changed

+98
-75
lines changed
  • 1-js/04-object-basics/07-optional-chaining
  • 9-regular-expressions/15-regexp-catastrophic-backtracking

2 files changed

+98
-75
lines changed

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

+25-19
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,23 @@
33

44
[recent browser="new"]
55

6-
The optional chaining `?.` is an error-proof way to access nested object properties, even if an intermediate property doesn't exist.
6+
The optional chaining `?.` is a safe way to access nested object properties, even if an intermediate property doesn't exist.
77

8-
## The problem
8+
## The "non-existing property" problem
99

1010
If you've just started to read the tutorial and learn JavaScript, maybe the problem hasn't touched you yet, but it's quite common.
1111

12-
For example, some of our users have addresses, but few did not provide them. Then we can't safely read `user.address.street`:
12+
As an example, let's consider objects for user data. Most of our users enter addresses, but some did not provide them.
13+
14+
In such case, when we attempt to get `user.address.street`, we'll get an error:
1315

1416
```js run
1517
let user = {}; // the user happens to be without address
1618

1719
alert(user.address.street); // Error!
1820
```
1921

20-
Or, in the web development, we'd like to get an information about an element on the page, but it may not exist:
22+
Another example. In the web development, we may need to get an information about an element on the page, that sometimes doesn't exist:
2123

2224
```js run
2325
// Error if the result of querySelector(...) is null
@@ -34,7 +36,7 @@ let user = {}; // user has no address
3436
alert( user && user.address && user.address.street ); // undefined (no error)
3537
```
3638

37-
AND'ing the whole path to the property ensures that all components exist, but is cumbersome to write.
39+
AND'ing the whole path to the property ensures that all components exist (if not, the evaluation stops), but is cumbersome to write.
3840

3941
## Optional chaining
4042

@@ -70,7 +72,7 @@ We should use `?.` only where it's ok that something doesn't exist.
7072

7173
For example, if according to our coding logic `user` object must be there, but `address` is optional, then `user.address?.street` would be better.
7274

73-
So, if `user` happens to be undefined due to a mistake, we'll know about it and fix it. Otherwise, coding errors can be silenced where not appropriate, and become more difficult to debug.
75+
So, if `user` happens to be undefined due to a mistake, we'll see a programming error about it and fix it. Otherwise, coding errors can be silenced where not appropriate, and become more difficult to debug.
7476
```
7577
7678
````warn header="The variable before `?.` must be declared"
@@ -80,25 +82,27 @@ If there's no variable `user` at all, then `user?.anything` triggers an error:
8082
// ReferenceError: user is not defined
8183
user?.address;
8284
```
83-
There must be `let/const/var user`. The optional chaining works only for declared variables.
85+
There must be a declaration (e.g. `let/const/var user`). The optional chaining works only for declared variables.
8486
````
8587

8688
## Short-circuiting
8789

8890
As it was said before, the `?.` immediately stops ("short-circuits") the evaluation if the left part doesn't exist.
8991
90-
So, if there are any further function calls or side effects, they don't occur:
92+
So, if there are any further function calls or side effects, they don't occur.
93+
94+
For instance:
9195

9296
```js run
9397
let user = null;
9498
let x = 0;
9599
96-
user?.sayHi(x++); // nothing happens
100+
user?.sayHi(x++); // no "sayHi", so the execution doesn't reach x++
97101
98102
alert(x); // 0, value not incremented
99103
```
100104

101-
## Other cases: ?.(), ?.[]
105+
## Other variants: ?.(), ?.[]
102106

103107
The optional chaining `?.` is not an operator, but a special syntax construct, that also works with functions and square brackets.
104108

@@ -121,9 +125,9 @@ user2.admin?.();
121125
*/!*
122126
```
123127
124-
Here, in both lines we first use the dot `.` to get `admin` property, because the user object must exist, so it's safe read from it.
128+
Here, in both lines we first use the dot (`user1.admin`) to get `admin` property, because the user object must exist, so it's safe read from it.
125129
126-
Then `?.()` checks the left part: if the admin function exists, then it runs (for `user1`). Otherwise (for `user2`) the evaluation stops without errors.
130+
Then `?.()` checks the left part: if the admin function exists, then it runs (that's so for `user1`). Otherwise (for `user2`) the evaluation stops without errors.
127131
128132
The `?.[]` syntax also works, if we'd like to use brackets `[]` to access properties instead of dot `.`. Similar to previous cases, it allows to safely read a property from an object that may not exist.
129133
@@ -148,19 +152,23 @@ Also we can use `?.` with `delete`:
148152
delete user?.name; // delete user.name if user exists
149153
```
150154
151-
```warn header="We can use `?.` for safe reading and deleting, but not writing"
152-
The optional chaining `?.` has no use at the left side of an assignment:
155+
````warn header="We can use `?.` for safe reading and deleting, but not writing"
156+
The optional chaining `?.` has no use at the left side of an assignment.
153157
158+
For example:
154159
```js run
155-
// the idea of the code below is to write user.name, if user exists
160+
let user = null;
156161

157162
user?.name = "John"; // Error, doesn't work
158163
// because it evaluates to undefined = "John"
159164
```
160165
166+
It's just not that smart.
167+
````
168+
161169
## Summary
162170
163-
The `?.` syntax has three forms:
171+
The optional chaining `?.` syntax has three forms:
164172
165173
1. `obj?.prop` -- returns `obj.prop` if `obj` exists, otherwise `undefined`.
166174
2. `obj?.[prop]` -- returns `obj[prop]` if `obj` exists, otherwise `undefined`.
@@ -170,6 +178,4 @@ As we can see, all of them are straightforward and simple to use. The `?.` check
170178
171179
A chain of `?.` allows to safely access nested properties.
172180
173-
Still, we should apply `?.` carefully, only where it's ok that the left part doesn't to exist.
174-
175-
So that it won't hide programming errors from us, if they occur.
181+
Still, we should apply `?.` carefully, only where it's acceptable that the left part doesn't to exist. So that it won't hide programming errors from us, if they occur.

0 commit comments

Comments
 (0)