Skip to content

Commit 6d80964

Browse files
committed
types-grammar: rearranging to split ch1 and ch2
1 parent 4366576 commit 6d80964

File tree

4 files changed

+69
-59
lines changed

4 files changed

+69
-59
lines changed

types-grammar/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@
99
* [Foreword](foreword.md) (by TBA)
1010
* [Preface](../preface.md)
1111
* [Chapter 1: Primitives](ch1.md)
12-
* Chapter 2: TODO
12+
* [Chapter 2: Value Behavior](ch2.md)
13+
* Chapter 3: TODO

types-grammar/ch1.md

Lines changed: 27 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ In Chapter 1 of the "Objects & Classes" book of this series, we confronted the c
99

1010
Here, we'll look at the core value types of JS, specifically the non-object types called *primitives*.
1111

12-
## Built-in Values
12+
## Value Types
1313

14-
JS provides seven built-in, primitive (non-object) value types:
14+
JS doesn't apply types to variables or properties -- what I call, "container types" -- but rather, values themselves have types -- what I call, "value types".
15+
16+
The language provides seven built-in, primitive (non-object) value types:
1517

1618
* `null`
1719
* `undefined`
@@ -21,9 +23,7 @@ JS provides seven built-in, primitive (non-object) value types:
2123
* `bigint`
2224
* `symbol`
2325

24-
JS doesn't apply types to variables or properties -- what I call, "container types" -- but rather, values themselves have types -- what I call, "value types".
25-
26-
These value-types define collections of one or more concrete values. Each value-type has a shared set of expected behaviors for all values of that type.
26+
These value-types define collections of one or more concrete values, each with a set of shared behaviors for all values of that type.
2727

2828
### Type-Of
2929

@@ -48,7 +48,7 @@ typeof greeting; // "string"
4848

4949
JS variables themselves don't have types. They hold any arbitrary value, which itself has a value-type.
5050

51-
### Empty Values
51+
## Empty Values
5252

5353
The `null` and `undefined` types both typically represent an emptiness or absence of value.
5454

@@ -83,7 +83,7 @@ typeof whatever[10]; // "undefined"
8383

8484
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.
8585

86-
#### Null'ish
86+
### Null'ish
8787

8888
Semantically, `null` and `undefined` types both represent general emptiness, or absence of another affirmative, meaningful value.
8989

@@ -164,7 +164,7 @@ The `?.(` operator seems like it is checking to see if `someFunc(..)` is a valid
164164
| :--- |
165165
| Because of that gotcha, I *strongly dislike* this operator form, and caution anyone against ever using it. I think it's a poorly conceived feature that does more harm (to JS itself, and to programs) than good. There's very few JS features I would go so far as to say, "never use it." But this is one of the truly *bad parts* of the language, in my opinion. |
166166
167-
#### Distinct'ish
167+
### Distinct'ish
168168
169169
It's important to keep in mind that `null` and `undefined` *are* actually distinct types, and thus `null` can be noticeably different 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 more often distinct.
170170
@@ -186,7 +186,7 @@ The `= ..` clause on a parameter is referred to as the "parameter default". It o
186186
187187
There's no *right* or *wrong* way to use `null` or `undefined` in a program. So the takeaway is: be careful when choosing one value or the other. And if you're using them interchangeably, be extra careful.
188188
189-
### Boolean Values
189+
## Boolean Values
190190
191191
The `boolean` type contains two values: `false` and `true`.
192192
@@ -214,7 +214,7 @@ while (!isComplete) {
214214
215215
The `!` operator negates/flips a boolean value to the other one: `false` becomes `true`, and `true` becomes `false`.
216216
217-
### String Values
217+
## String Values
218218
219219
The `string` type contains any value which is a collection of one or more characters, delimited (surrounding on either side) by quote characters:
220220
@@ -234,7 +234,7 @@ myName.length; // 4
234234
235235
This does not necessarily correspond to the number of visible characters present between the start and end delimiters (aka, the string literal). It can sometimes be a little confusing to keep straight the difference between a string literal and the underlying string value, so pay close attention.
236236
237-
#### JS Character Encodings
237+
### JS Character Encodings
238238
239239
What type of character encoding does JS use for string characters?
240240
@@ -250,7 +250,7 @@ This has implications on the length of strings, because a single visible charact
250250
251251
We'll revisit Unicode characters shortly.
252252
253-
#### Escape Sequences
253+
### Escape Sequences
254254
255255
If `"` or `'` are used to delimit a string literal, the contents are only parsed for *character-escape sequences*: `\` followed by one or more characters that JS recognizes and parses with special meaning. Any other characters in a string that don't parse as escape-sequences (single-character or multi-character), are inserted as-is into the string value.
256256

@@ -285,7 +285,7 @@ console.log(windowsFontsPath);
285285
| :--- |
286286
| What about four backslashes `\\\\` in a string literal? Well, that's just two `\\` escape sequences next to each other, so it results in two adjacent backslashes (`\\`) in the underlying string value. You might recognize there's an odd/even rule pattern at play. You should thus be able to deciper any odd (`\\\\\`, `\\\\\\\\\`, etc) or even (`\\\\\\`, `\\\\\\\\\\`, etc) number of backslashes in a string literal. |
287287
288-
#### Multi-Character Escapes
288+
### Multi-Character Escapes
289289
290290
Multi-character escape sequences may be hexadecimal or Unicode sequences.
291291
@@ -303,7 +303,7 @@ For any normal character that can be typed on a keyboard, such as `"a"`, it's us
303303
"a" === "\x61"; // true
304304
```
305305
306-
##### Unicode
306+
#### Unicode
307307
308308
Unicode escape sequences encode any of the characters in the Unicode set whose code-point values range from 0-65535. They look like `\u` followed by exactly four hexadecimal characters. For example, the escape-sequence `\u00A9` (or `\u00a9`) corresponds to that same `©` symbol, while `\u263A` (or `\u263a`) corresponds to the Unicode character with code-point `9786`: `` (smiley face symbol).
309309
@@ -338,7 +338,7 @@ All three representations of this same character are stored internally by JS ide
338338
339339
Even though JS doesn't care which way such a character is represented in your program, consider the readability differences carefully when authoring your code.
340340
341-
#### Line Continuation
341+
### Line Continuation
342342
343343
The `\` followed by an actual new-line character (not just literal `n`) is a special case, and it creates what's called a line-continuation:
344344
@@ -358,7 +358,7 @@ Because the end-of-line `\` turns the new-line character into a line continuatio
358358
| :--- |
359359
| This line-continuation feature is often referred to as "multi-line strings", but I think that's a confusing label. As you can see, the string value itself doesn't have multiple lines, it only was defined across multiple lines via the line continuations. A multi-line string would actually have multiple lines in the underlying value. |
360360
361-
#### Template Literals
361+
### Template Literals
362362
363363
I mentioned earlier that strings can alternately be delimited with `` `..` `` back-ticks:
364364
@@ -423,7 +423,7 @@ Moreover, there are a few places where `` `..` `` style strings are disallowed.
423423
424424
My take: use `` `..` `` delimited strings where allowed, but only when interpolation/multi-line is needed; and keep using `".."` or `'..'` delimited strings for everything else.
425425
426-
### Number Values
426+
## Number Values
427427
428428
The `number` type contains any numeric value (whole number or decimal), such as `-42` or `3.1415926`. These values are represented by the JS engine as 64-bit, IEEE-754 double-precision binary floating-point values. [^IEEE754]
429429
@@ -439,7 +439,7 @@ Number.isInteger(42.000000); // true
439439
Number.isInteger(42.0000001); // false
440440
```
441441
442-
#### Parsing vs Coercion
442+
### Parsing vs Coercion
443443
444444
If a string value holds numeric-looking contents, you may need to convert from that string value to a `number`, for mathematical operation purposes.
445445
@@ -482,7 +482,7 @@ Number("512px"); // NaN
482482
+"512px"; // NaN
483483
```
484484
485-
#### IEEE-754 Bitwise Binary Representations
485+
### IEEE-754 Bitwise Binary Representations
486486
487487
IEEE-754[^IEEE754] is a technical standard for binary representation of decimal numbers. It's widely used by most computer programming languages, including JS, Python, Ruby, etc.
488488
@@ -525,7 +525,7 @@ Notice how the previous bit pattern and this one differ by quite a few bits in t
525525
526526
Now you understand a *bit more* about how IEEE-754 works!
527527
528-
##### Floating Point Imprecision
528+
#### Floating Point Imprecision
529529
530530
One of the classic gotchas of any IEEE-754 number system in any programming language -- NOT UNIQUELY JS! -- is that not all operations and values can fit neatly into the IEEE-754 representations.
531531
@@ -567,7 +567,7 @@ Pretty much all programmers need to be aware of IEEE-754 and make sure they are
567567
| :--- |
568568
| Shortly, we'll cover `Number.EPSILON`, which offers an approach to working around this floating point error situation when comparing numbers. |
569569
570-
#### Number Limits
570+
### Number Limits
571571
572572
As might be evident now that you've seen how IEEE-754 works, the 52 bits of the number's base must be shared, representing both the whole number portion (if any) as well as the decimal portion (if any), of the intended `number` value. Essentially, the larger the whole number portion to be represented, the less bits are available for the decimal portion, and vice versa.
573573
@@ -630,7 +630,7 @@ Number.MIN_VALUE; // 5e-324 <-- usually!
630630
631631
Most JS engines seem to have a minimum representable value around `5E-324` (about `2^-1074`). Depending on the engine and/or platform, a different value may be exposed. Be careful about any program logic that relies on such implementation-dependent values.
632632
633-
#### Safely Small
633+
### Safely Small
634634
635635
There's another *very small* `number` value you may want to use:
636636
@@ -660,7 +660,7 @@ Since JS cannot represent a difference between two values smaller than this `Num
660660
| :--- |
661661
| If your program needs to deal with smaller values, or more specifically, smaller differences between values, than `2^-52`, you should absolutely *not use* the `number` value-type. There are decimal-emulation libraries that can offer arbitrary (small or large) precision. Or pick a different language than JS. |
662662
663-
#### Safe Integer Limits
663+
### Safe Integer Limits
664664
665665
Since `Number.MAX_VALUE` is an integer, you might assume that it's the largest integer in the language. But that's not really accurate.
666666
@@ -686,7 +686,7 @@ Depending on how you interpret "smallest", you could either answer `0` or... `Nu
686686
Number.MIN_SAFE_INTEGER; // -9007199254740991
687687
```
688688
689-
#### Double Zeros
689+
### Double Zeros
690690
691691
It may surprise you to learn that JS has two zeros: `0`, and `-0` (negative zero). But what on earth is a "negative zero"? A mathematician would surely balk at such a notion.
692692
@@ -712,7 +712,7 @@ You may wonder why we'd ever need such a thing as `-0`. It can be useful when us
712712
713713
Without having a signed zero value, you couldn't tell which direction such an item was pointing at the moment it came to rest.
714714
715-
#### Invalid Number
715+
### Invalid Number
716716
717717
Mathematical operations can sometimes produce an invalid result. For example:
718718
@@ -772,7 +772,7 @@ If you're not properly checking for `NaN` in your programs where you do math or
772772
| :--- |
773773
| JS originally provided a global function called `isNaN(..)` for `NaN` checking, but it unfortunately has a long-standing coercion bug. `isNaN("Kyle")` returns `true`, even though the string value `"Kyle"` is most definitely *not* the `NaN` value. This is because the global `isNaN(..)` function forces any non-`number` argument to coerce to a `number` first, before checking for `NaN`. Coercing `"Kyle"` to a `number` produces `NaN`, so now the function sees a `NaN` and returns `true`! This buggy global `isNaN(..)` still exists in JS, but should never be used. When `NaN` checking, always use `Number.isNaN(..)`, `Object.is(..)`, etc. |
774774
775-
### BigInteger Values
775+
## BigInteger Values
776776
777777
As the maximum safe integer in JS `number`s is `9007199254740991`, such a relatively low limit can present a problem if a JS program needs to do larger integer math, or even just hold values like 64-bit integer IDs (e.g., Twitter Tweet IDs).
778778
@@ -838,7 +838,7 @@ Unlike `parseInt(..)`, if any character in the string is non-numeric (`0-9` digi
838838
| :--- |
839839
| I think it's absurd that `BigInt(..)` won't accept the trailing `n` character while string parsing (and effectively ignore it). I lobbied vehemently for that in the TC39 process, but was ultimately denied. In my opinion, it's now a tiny little wart on JS, but a wart nonetheless. |
840840
841-
### Symbol Values
841+
## Symbol Values
842842
843843
The `symbol` type contains special opaque values called "symbols". These values can only be created by the `Symbol(..)` function:
844844
@@ -858,36 +858,6 @@ Symbols are guaranteed by the JS engine to be unique (only within the program it
858858
859859
// TODO
860860
861-
## Value Immutability
862-
863-
All primitive values are immutable, meaning nothing in a JS program can reach into the inside of the value and modify it in any way.
864-
865-
New values are created through operations, but these do not modify the original value.
866-
867-
```js
868-
42 + 1; // 43
869-
870-
"Hello" + "!"; // "Hello!"
871-
```
872-
873-
The values `43` and `"Hello!"` are new, distinct values from the `42` and `"Hello"` values, respectively.
874-
875-
// TODO
876-
877-
## Assignments Are Value Copies
878-
879-
Any assignment of a value from one variable/container to another is a *value-copy*.
880-
881-
```js
882-
myAge = 42;
883-
884-
yourAge = myAge; // assigned by value-copy
885-
```
886-
887-
Here, the `myAge` and `yourAge` variables each have their own copy of the number value `42`. That means if we later re-assign `myAge` to `43` when I have a birthday, it doesn't affect the `42` that's still assigned to `yourAge`.
888-
889-
// TODO
890-
891861
[^UTFUCS]: "JavaScript’s internal character encoding: UCS-2 or UTF-16?"; Mathias Bynens; January 20 2012; https://mathiasbynens.be/notes/javascript-encoding ; Accessed July 2022
892862
893863
[^IEEE754]: "IEEE-754"; https://en.wikipedia.org/wiki/IEEE_754 ; Accessed July 2022

types-grammar/ch2.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# You Don't Know JS Yet: Types & Grammar - 2nd Edition
2+
# Chapter 2: Value Behavior
3+
4+
## Value Immutability
5+
6+
All primitive values are immutable, meaning nothing in a JS program can reach into the inside of the value and modify it in any way.
7+
8+
New values are created through operations, but these do not modify the original value.
9+
10+
```js
11+
42 + 1; // 43
12+
13+
"Hello" + "!"; // "Hello!"
14+
```
15+
16+
The values `43` and `"Hello!"` are new, distinct values from the `42` and `"Hello"` values, respectively.
17+
18+
// TODO
19+
20+
## Assignments Are Value Copies
21+
22+
Any assignment of a value from one variable/container to another is a *value-copy*.
23+
24+
```js
25+
myAge = 42;
26+
27+
yourAge = myAge; // assigned by value-copy
28+
```
29+
30+
Here, the `myAge` and `yourAge` variables each have their own copy of the number value `42`. That means if we later re-assign `myAge` to `43` when I have a birthday, it doesn't affect the `42` that's still assigned to `yourAge`.
31+
32+
// TODO

types-grammar/toc.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@
99
* Foreword
1010
* Preface
1111
* Chapter 1: Primitives
12-
* Built-in Values
12+
* Value Types
13+
* Empty Values
14+
* Boolean Values
15+
* String Values
16+
* Number Values
17+
* BigInteger Values
18+
* Symbol Values
19+
* Chapter 2: Value Behavior
1320
* Value Immutability
1421
* Assignments Are Value Copies
1522
* TODO

0 commit comments

Comments
 (0)