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/ch1.md
+82-7Lines changed: 82 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -39,14 +39,14 @@ typeof 42n; // "bigint"
39
39
typeofSymbol("42"); // "symbol"
40
40
```
41
41
42
-
The `typeof` operator, when used against a variable, is reporting the value-type of the value in the variable:
42
+
The `typeof` operator, when used against a variable instead of a value, is reporting the value-type of *the value in the variable*:
43
43
44
44
```js
45
45
greeting ="Hello";
46
46
typeof greeting; // "string"
47
47
```
48
48
49
-
Again, JS variables themselves don't have types. They hold any arbitrary value, which itself has a value-type.
49
+
JS variables themselves don't have types. They hold any arbitrary value, which itself has a value-type.
50
50
51
51
### Empty Values
52
52
@@ -58,7 +58,7 @@ The `null` value-type has an unexpected `typeof` result. Instead of `"null"`, we
58
58
typeofnull; // "object"
59
59
```
60
60
61
-
No, that doesn't mean that `null` is somehow a special kind of object. It's just a legacy of early days of JS, which cannot be changed because of how much code out in the wild it could break.
61
+
No, that doesn't mean that `null` is somehow a special kind of object. It's just a legacy of early days of JS, which cannot be changed because of how much code out in the wild it would break.
62
62
63
63
The `undefined` type is reported both for explicit `undefined` values and any place where a seemingly missing value is encountered:
| The `typeof nonExistent` expression is referring to an undeclared variable `nonExisttent`. Normally, an undeclared variable reference might cause an exception (in strict mode), but the `typeof` operator is afforded the special ability to safely access even non-existent identifiers and calmly return `"undefined"` instead of throwing an exception. |
82
+
| The `typeof nonExistent` expression is referring to an undeclared variable `nonExisttent`. Normally, accessing an undeclared variable reference would cause an exception, but the `typeof` operator is afforded the special ability to safely access even non-existent identifiers and calmly return `"undefined"` instead of throwing an exception. |
83
83
84
-
However, each respective type has exactly one value, of the same name. So `null` is the only value in the `null` value-type, and `undefined` is the only value in the `undefined` value-type.
84
+
However, each respective "empty" type has exactly one value, of the same name. So `null` is the only value in the `null` value-type, and `undefined` is the only value in the `undefined` value-type.
85
85
86
-
// TODO
86
+
#### Null'ish
87
+
88
+
Semantically, `null` and `undefined` types both represent emptiness, or absence of another affirmative, meaningful value.
89
+
90
+
| NOTE: |
91
+
| :--- |
92
+
| JS operations which behave the same whether `null` or `undefined` is encountered, are referred to as "null'ish" (or "nullish"). I guess "undefined'ish" would look/sound too weird! |
93
+
94
+
For a lot of JS, especially the code developers write, these two *nullish* values are interchangeable; the decision to intentionally use/assign `null` or `undefined` in any given scenario is situation dependent and left up to the developer.
95
+
96
+
JS provides a number of capabilities for helping treat the two nullish values as indistinguishable.
97
+
98
+
For example, the `==` (coercive-equality comparision) operator specifically treats `null` and `undefined` as coercively equal to each other, but to no other values in the language. As such, as `.. == null` check is safe to perform if you want to check if a value is specifically either `null` or `undefined`:
99
+
100
+
```js
101
+
if (greeting ==null) {
102
+
// greeting is nullish/empty
103
+
}
104
+
```
105
+
106
+
Another (recent) addition to JS is the `??` (nullish-coalescing) operator:
107
+
108
+
```js
109
+
who = myName ??"User";
110
+
111
+
// equivalent to:
112
+
who = (myName !=null) ? myName :"User";
113
+
```
114
+
115
+
As the ternary equivalent illustrates, `??` checks to see if `myName` is non-nullish, and if so, returns its value. Otherwise, it returns the other operand (here, `"User"`).
116
+
117
+
Along with `??`, JS also added the `?.` (nullish conditional-chaining) operator:
118
+
119
+
```js
120
+
record = {
121
+
shippingAddress: {
122
+
street:"123 JS Lane",
123
+
city:"Browserville",
124
+
state:"XY"
125
+
}
126
+
};
127
+
128
+
console.log( record?.shippingAddress?.street );
129
+
// 123 JS Lane
130
+
131
+
console.log( record?.billingAddress?.street );
132
+
// undefined
133
+
```
134
+
135
+
The `?.` operator checks the value immediately preceding (to the left) value, and if it's nullish, the operator stops and returns an `undefined` value. Otherwise, it performs the `.` property access against that value and continues with the expression.
136
+
137
+
Just to be clear: `record?.` is saying, "check `record` for nullish before `.` property access". Additionally, `billingAddress?.` is saying, "check `billingAddress` for nullish before `.` property access".
138
+
139
+
| WARNING: |
140
+
| :--- |
141
+
| Some JS developers believe that the newer `?.` is superior to `.`, and should thus almost always be used instead of `.`. I believe that's an unwise perspective. First of all, it's adding extra visual clutter, which should only be done if you're getting benefit from it. Secondly, you should be aware of, and planning for, the emptiness of some value, to justify using `?.`. If you always expect a non-nullish value to be present in some expression, using `?.` to access a property on it is not only unnecessary/wasteful, but also could potentially hide future bugs where your assumption of value-presence had failed but `?.` covered it up. As with most features in JS, use `.` where it's most appropriate, and use `?.` where it's most appropriate. Never substitute one when the other is more appropriate. |
142
+
143
+
#### Distint'ish
144
+
145
+
It's important to keep in mind that `null` and `undefined` *are* actually distinct types, and thus `null` is quite noticeably distinct from `undefined`. You can, carefully, construct programs that mostly treat them as indistinguishable. But that requires care and discipline by the developer. From JS's perspective, they're often distinct.
146
+
147
+
There are cases where `null` and `undefined` will trigger different behavior by the language, which is important to keep in mind. We won't cover all the cases exhaustively here, but here's on example:
148
+
149
+
```js
150
+
functiongreet(msg="Hello") {
151
+
console.log(msg);
152
+
}
153
+
154
+
greet(); // Hello
155
+
greet(undefined); // Hello
156
+
greet("Hi"); // Hi
157
+
158
+
greet(null); // null
159
+
```
160
+
161
+
The `= ..` clause on a parameter is referred to as the "parameter default". It only kicks in and assigns its default value to the parameter if the argument in that position is missing, or is exactly the `undefined` value. If you pass `null`, that clause doesn't trigger, and `null` is thus assigned to the parameter.
87
162
88
163
### Boolean Values
89
164
90
-
The `boolean` type contains two values: `true` and `false`.
165
+
The `boolean` type contains two values: `false` and `true`.
0 commit comments