You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: types-grammar/ch4.md
+68-2Lines changed: 68 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -964,7 +964,25 @@ We can see the `0` / `-0` misdirection of `SameValueZero()` here:
964
964
(newMap([[ 0, "ok" ]])).has(-0); // true <--- :(
965
965
```
966
966
967
-
In these cases, there's a *coercion* (of sorts!) that treats `-0` and `0` as indistinguishable. No, that's not technically a *coercion* in that the type is not being changed, but I'm sort of fudging the definition to *include* this case in our broader discussion of coercion here.
967
+
In these cases, there's a *coercion* (of sorts!) that treats `-0` and `0` as indistinguishable. No, that's not technically a "coercion" in that the type is not being changed, but I'm sort of fudging the definition to *include* this case in our broader discussion of coercion here.
968
+
969
+
Contrast the `includes()` / `has()` methods here, which activate `SameValueZero()`, with the good ol' `indexOf(..)` array utility, which instead activates `IsStrictlyEqual()` instead. This algorithm is slightly more "coercive" than `SameValueZero()`, in that it prevents `NaN` values from ever being treated as equal to each other:
970
+
971
+
```js
972
+
[ 1, 2, NaN ].indexOf(NaN); // -1 <--- not found
973
+
```
974
+
975
+
If these nuanced quirks of `includes(..)` and `indexOf(..)` bother you, when searching -- looking for an equality match within -- for a value in an array, you can avoid any "coercive" quicks and *force* the strictest `SameValue()` equality matching, via `Object.is(..)`:
976
+
977
+
```js
978
+
vals = [ 0, 1, 2, -0, NaN ];
979
+
980
+
vals.find(v=>Object.is(v,-0)); // -0
981
+
vals.find(v=>Object.is(v,NaN)); // NaN
982
+
983
+
vals.findIndex(v=>Object.is(v,-0)); // 3
984
+
vals.findIndex(v=>Object.is(v,NaN)); // 4
985
+
```
968
986
969
987
#### Equality Operators: `==` vs `===`
970
988
@@ -1005,7 +1023,55 @@ I'll be revisiting this topic to make the case for preferring `==` over `===`, l
1005
1023
1006
1024
#### Nullish Coercion
1007
1025
1008
-
// TODO
1026
+
We've already seen a number ofJS operations that are nullish -- treating `null` and `undefined` as coercively equal to each other, including the `?.` optional-chaining operator and the `??` nullish-coalescing operator (see "Null'ish"in Chapter 1).
1027
+
1028
+
But `==` is the most obvious place that JS exposes nullish coercive equality:
1029
+
1030
+
```js
1031
+
null == undefined; // true
1032
+
```
1033
+
1034
+
Neither `null` nor `undefined` will ever be coercively equal to any other value in the language, other than to each other. That means `==` makes it ergonomic to treat these two values as indistinguishable.
1035
+
1036
+
You might take advantage ofthis capability as such:
1037
+
1038
+
```js
1039
+
if (someData == null) {
1040
+
// `someData` is "unset" (either null or undefined),
1041
+
// so set it to some default value
1042
+
}
1043
+
1044
+
// OR:
1045
+
1046
+
if (someData != null) {
1047
+
// `someData` is set (neither null nor undefined),
1048
+
// so use it somehow
1049
+
}
1050
+
```
1051
+
1052
+
Remember that `!=` is the negation of`==`, whereas `!==` is the negation of`===`. Don't match the count of `=`s unless you want to confuse yourself!
1053
+
1054
+
Compare these two approaches:
1055
+
1056
+
```js
1057
+
if (someData == null) {
1058
+
// ..
1059
+
}
1060
+
1061
+
// vs:
1062
+
1063
+
if (someData === null || someData === undefined) {
1064
+
// ..
1065
+
}
1066
+
```
1067
+
1068
+
Both `if` statements will behave exactly identically. Which one would you rather write, and which one would you rather read later?
1069
+
1070
+
To be fair, some of you prefer the more verbose `===` equivalent. And that's OK. I disagree, I think the `==` version ofthis check is *much*better. AndI also maintain that the `==` version is more consistent in stylistic spirit with how the other nullish operators like `?.` and `??` act.
1071
+
1072
+
But another minor fact you might consider:inperformance benchmarks I've run many times, JS engines can perform the single `== null` check as shown *slightly faster* than the combination of two `===` checks. In other words, there's a tiny but measurable benefit to letting JS's `==` perform the *implicit* nullish coercion than in trying to *explicitly* list out both checks yourself.
1073
+
1074
+
I'd observe that even many diehard `===` fans tend to concede that `== null` is at least one such case where `==` is preferable.
0 commit comments