Studied up to Chap3.6

master
Jason Zhu 2021-01-09 05:51:20 +00:00
parent 4942e000b8
commit 60babc0a8a
1 changed files with 535 additions and 0 deletions

View File

@ -0,0 +1,535 @@
# Chapter 3. Types, Values, and Variables
## 3.1 Overview and Definitions
JS types has 2 categories of data types:
* **primitive** types: numeric, string, boolean, special JS values (`null` & `undefined`)
* **object** types: any JS values that not primitive types.
* It's a collection of properties where each property has a name and a value (primitive or object)
* Ordinary JS object is unordered collection of named values.
* Special JS object like
* **Array** defined in JS is an ordered collection of numbered values.
* **Map**: mapping from keys to values
* **Set**: set of values
* **"typed array" types** for operations on array of bytes/binary
* **RegExp** for textual patterns
* **Date** type for date & times
* **Error & subtypes** for errors when executing JS code.
Functional Programming of JS:
* Functions/Classes are not just part of language syntax, but they are also values that can be manipulated by JS
Garbage collection of JS:
* JS interpreter automatically collect garbage for memory management.
OOP of JS:
* type themselves define methods for working with values. e.g. `a.sort()`
Mutable/Immutable of JS:
* Primitive types are **immutable**: number, booleans
* Object types are **immutable**: change array
Value convertion of JS:
* JS convert values automatically (e.g. from number to string)
* Certain rules are there.
Constant & Variable declaration:
* Constant & Variables allow programmer to refer values using names.
* Declare constant using `const`
* Declare variable using `let` (for new JS), or `var` for old JS version
* Constant & Variables are *untyped* (i.e. declaration do no specify type of assigned values)
## 3.2 Numbers
Number:
* JS's primitive numeric type
* Represent *Integers* & *Float*
* Using 64-bit floating point format
* large as +/- 1.79769x10^308
* Small as +/- 5 x 10^-324
When a number appears directly in JS code, it's **numerical literal**
### 3.2.1 Integer Literals
* Base-10 integer: `0`, `3`, `100000`
* Hexadecimal (base-16) values: `0xff`, `0xBADCAFE`
* Binary (base 2) & Octal (base 8) after ES6: `0b10101`, `0o377`
### 3.2.2 Floating-Point Literals
* Traditional notation: `3.14`, `2345.6789`
* Exponential notation: `6.02e23` means `6.02 x 10^23`
#### Separations in numeric literals
Future JS format will recognize `_` within numeric literals for breaking long literals
e.g.:
* `let billion = 1_000_000_000;`
* `let bytes = 0x89_AB_CD_EF;`
### 3.2.3 Arithmetic in JS
Basic Arithmetic operators:
* addition: `+`
* subtraction: `-`
* multiplication: `*`
* division: `/`
* modulo: `%`
* exponentiation: `**`
`Math` object has more complex math operations, check reference for details:
* `Math.pow(2,53)`
* `Math.round(.6)`
* ...
Note:
* Arithmetic in JS do not raise errors for *overflow*/*underflow*/*division by 0*
* Overflow (result is larger than largest representable number) -> `Infinity`
* Underflow (result is smaller than smallest representable) -> `-Inifinity`
* Division by 0 return either `Infinity` or `-Inifinity`
* `0/0` return `NaN` (**Not a Number**) as the value is not well-defined
* `Infinity/Infinity` return `NaN`
JS predefined a series of global constants:
* `Infinity`
* `Number.POSITIVE_INFINITY`
* `1/0`
* ...
check reference for all global constant information
* `NaN` cannot compare to other value (others can)
* Solution to the problem: `x != x` or `Number.isNaN(x)` for comparison
### 3.2.4 Binary Floating-Point and Rounding Errors
Real number in real life is continuous & infinite. But due to computer is binary, only finite number of them can be represented by JS floating-point format. Hence, in JS, real number are approximation of the actual number.
JS us IEEE-754 floating-point representation (a binary representation, that can only represent 1/2, 1/7, 1/1024). Number like `.1` (i.e. `1/10`) can only be approximated
This problem is generic across computing language using binary representation. Solution include: **manipulate monetary values as integer cents rather than fractional dollars**
### 3.2.5 Arbitrary Precision Integers with BigInt
New numeric type **BigInt** (new features of JS) defined in ES2020.
```js
1234n // not-so-big BigInt
0b1111n // Binary BigInt
0o7777n // Octal BigInt
0x800000000n
```
BigInt:
* a numeric type for large **(64-bit) integer**
* BigInt literals are shown above. (i.e. digits followed by `n`)
* Can convert from other number using `BigInt()`
```js
BigInt(Number.MAX_SAFE_INTEGEG) // => 900719925474099n
let string = "1" + "0".repeat(100); // 1 followed by 100 zeros
BigInt(string)
```
Arithmetic operations with BigInt:
```js
1000n + 2000n
3000n - 2000n
2000n * 3000n
3000n / 997n
...
```
### 3.2.6 Dates and Times
JS has simple Date class, the timestamp count since Jan 1, 1970
```js
let timestamp = Date.now();
let now = new Date();
let ms = new.getTime(); // milisecond timestamp
let iso = now.toISOString(); // Convert to a string in standard format.
```
## 3.3 Text
* JS use *string* to represent text.
* *string* = immutable ordered sequence of 16-bit values.
* JS use **zero-based indexing** for string & array. i.e. 1st value start from 0
* empty string has length 0
JS strings & codepoints & characters
* JS uses UTF-16 encoding for characters.
* Most frequently used characters have 16bit **codepoints**
* Some Unicode characters cannot fit in 16bits, may be represented as a sequence of 2 16-bit values (i.e. **surrogate pair**) as shown below
```js
let euro = "€";
let love = "❤";
euro.length // => 1: this character has one 16-bit element
love.length // => 2: UTF-16 encoding of ❤ is "\ud83d\udc99"
```
* Pre ES6, looping through surrogate pair will treat each 16bit as independent value
* In ES6, strings are *iterable*, so iterator will recognize these surrogate pairs
### 3.3.1 String Literals
Pre ES6, Coding string literals in JS: cover literals within single/double quotes
* double/single quotes can be contained within single/double quotes
```js
"" // The empty string: it has zero characters
'testing' // single quotes
"3.14" // double quotes
'name="myform"' // double quotes contained within string delimited by single-quote
"Wouldn't you prefer O'Reilly's book?" //
"τ is the ratio of a circle's circumference to its radius"
```
In ES6, backticks is added to contain string literals, which allow JS expressions to be embedded within string literals
```js
`"She said 'hi'", he said.`
```
#### multi-line string and new line character sequence
Pre ES5: JS required string literals to be coded in single line.
* Common practice: String literals are broken into multi-lines by concatenated with `+`
In ES5: JS can break string into multilines by **backslash** `\`
```js
// A one-line string written on 3 lines:
"one\
long\
line"
```
In ES5: JS can create a two line string written in one line code using **new lien character sequence** `\n`
```js
// A string representing 2 lines written on one line:
'two\nlines'
```
In ES6: backtick allows strings to be broken into multiple lines, while line terminator are part of the string literal:
```js
// A two-line string written on two lines:
`the newline character at the end of this line
is included literally in this string`
```
#### JS & HTML mixed up
JS programming may contain strings of HTML code, while HTML code may contains strings of JS. Both JS & HTML use double/single quote for strings.
Common practice: use one style of quotes for JS and other style for HTML.
```html
<button onclick="alert('Thank you')">Click Me</button>
```
* string "Thank you" is single-quoted within a JS expression
* JS expression is then double-quoted within HTML event-handler attribute
### 3.3.2 Escape Sequences in String Literals
Backslash character `\` combined with specific character = **excape sequence**, which represent a special character
JS escape sequences
| Sequence | Character represented |
| -------- | ----------------------------------------------------------------------------------------------------------------------- |
| `\0` | NULL (\u0000) |
| `\b` | Backspace (\u0008) |
| `\t` | Horizontal tab (\u0009) |
| `\n` | Newline (\u000A) |
| `\v` | Vertical tab (\u000B) |
| `\f` | Form feed (\u000C) |
| `\r` | Carriage return (\u000D) |
| `\"` | Double quote (\u0022) |
| `\'` | Apostrophe or single quote (\u0027) |
| `\\` | Backslash (\u005C) |
| `\xnn` | The Unicode character specified by the two hexadecimal digits nn |
| `\unnnn` | The Unicode character specified by the four hexadecimal digits nnnn |
| `\u{n}` | The Unicode character specified by the codepoint n, where n is one to six hexadecimal digits between 0 and 10FFFF (ES6) |
### 3.3.3 Working with Strings
* concatenate strings (JS' built-in feature) using `+`:
```js
let msg = "Hello, " + "world"; // Produces the string "Hello, world"
let greeting = "Welcome to my blog," + " " + name;
```
* String comparison using `===` (equal) and `!==` (inequal).
* Comparison is done by checking 16-bit values
* Checking length of a string via length property of the string `.length`
Other than methods/property mentioned above, JS has rich API (methods):
```js
let s = "Hello, world"; // Start with some text.
// Obtaining portions of a string
s.substring(1,4) // => "ell": the 2nd, 3rd, and 4th characters.
s.slice(1,4) // => "ell": same thing
s.slice(-3) // => "rld": last 3 characters
s.split(", ") // => ["Hello", "world"]: split at delimiter string
// Searching a string
s.indexOf("l") // => 2: position of first letter l
s.indexOf("l", 3) // => 3: position of first "l" at or after 3
s.indexOf("zz") // => -1: s does not include the substring "zz"
s.lastIndexOf("l") // => 10: position of last letter l
// Boolean searching functions in ES6 and later
s.startsWith("Hell") // => true: the string starts with these
s.endsWith("!") // => false: s does not end with that
s.includes("or") // => true: s includes substring "or"
// Creating modified versions of a string
s.replace("llo", "ya") // => "Heya, world"
s.toLowerCase() // => "hello, world"
s.toUpperCase() // => "HELLO, WORLD"
s.normalize() // Unicode NFC normalization: ES6
s.normalize("NFD") // NFD normalization. Also "NFKC", "NFKD"
// Inspecting individual (16-bit) characters of a string
s.charAt(0) // => "H": the first character
s.charAt(s.length-1) // => "d": the last character
s.charCodeAt(0) // => 72: 16-bit number at the specified position
s.codePointAt(0) // => 72: ES6, works for codepoints > 16 bits
// String padding functions in ES2017
"x".padStart(3) // => " x": add spaces on the left to a length of 3
"x".padEnd(3) // => "x ": add spaces on the right to a length of 3
"x".padStart(3, "*") // => "**x": add stars on the left to a length of 3
"x".padEnd(3, "-") // => "x--": add dashes on the right to a length of 3
// Space trimming functions. trim() is ES5; others ES2019
" test ".trim() // => "test": remove spaces at start and end
" test ".trimStart() // => "test ": remove spaces on left. Also trimLeft
" test ".trimEnd() // => " test": remove spaces at right. Also trimRight
// Miscellaneous string methods
s.concat("!") // => "Hello, world!": just use + operator instead
"<>".repeat(5) // => "<><><><><>": concatenate n copies. ES6
```
* strings are immutable in JS. Methods shown above return new strings, instead of modifying original string
* strings can be read as array, `s[s.slength-1]` return 2nd last char
### 3.3.4 Template Literals
In ES6, backtickes are added:
```js
let s = `hello world`;
```
**Template literals** = string literal created using backticks
* it can include JS expression.
* its final value is computed by evaluating expression, convert these values into strings, combining to get result
* JS expression: `${ expression }`
* Everything outside `${}` is normal string literal text.
```js
let name = "Bill";
let greeting = `Hello ${ name }.`; // greeting == "Hello Bill."
```
* Template literal can include multiple expressions.
* Use any escape char
* Span multi-lines
```js
let errorMessage = `\ // backslash escape the initial newline
\u2718 Test failure at ${filename}:${linenumber}:
${exception.message}
Stack trace:
${exception.stack}
`;
```
#### Tagged template literals
**Tagged Template Literals**: Template literals's uncommonly used feature
* If a function name (also called "tag function") comes right before the opening backtick, (e.g. shown below)
* then the text and values of the expressions within the template literal are passed to the function
* And value of this **Tagged Template Literals** is the return value of the function
中文翻译:
* 如果 function name 在 opening backtick 之前
* 那 backtick 以内的文字和值都会被直接传递给 function
* 这个方程返回的值就是 **Tagged Template Literals** 的值
```js
`\n`.length // => 1: the string has a single newline character
String.raw`\n`.length // => 2: a backslash character and the letter n
// 这里 `\n` 作为 tagged template literals 被传递给了方程,而导致产生的结果不一样
```
Usage of Tagged Template Literals:
* Applying HTML or SQL escaping to the values before substuting them into the text
* etc.
We can define our own template tag function
### 3.3.5 Pattern Matching
* **RegExp (Regular Expression)**: a datatype defined by JS.
* Used for describing/matching string patterns.
* RegExp is not fundamental datatype in JS
* Grammer & API of RegExp is complex.
Grammer of RegExp:
* RegExp literal = Text btw a pair of slashes
* one or more letter can follow 2nd slash to change meaning of pattern
```js
/^HTML/; // Match the letters HTML at the start of a string
/[1-9][0-9]*/; // Match a nonzero digit, followed by any number of digits
/\bjavascript\b/i; // Match a "javascript" as a work, case-sensitive
```
API of RegExp datatype (e.g.):
```js
let text = "testing: 1, 2, 3"; // Sample text
let pattern = /\d+/g; // Matches all instances of one or more digits
pattern.test(text) // => true: a match exists
text.search(pattern) // => 9: position of first match
text.match(pattern) // => ["1", "2", "3"]: array of all matches
text.replace(pattern, "#") // => "testing: #, #, #"
text.split(/\D+/) // => ["","1","2","3"]: split on nondigits
```
## 3.4 Boolean Values
* **Boolean values**: evaluated using reserved words `true` & `false`
* Comparison in JS:
* Equal to: `===`. e.g. `a === 4`
* Not-Equal to: `!==`
* **Any** JS value can be converted to a boolean value:
* Following (i.e. **falsy values**) are converted to false.
* All values aren't falsy values are **truthy**
```js
undefined
null
0
-0
NaN
"" // the empty string
```
truthy values can be proven as shown:
```js
if (o!== null)...
```
Methods of Boolean values:
* `toString()`: convert `true` to "true".
3 Important boolean operator:
* `&&`: Boolean AND operator. It evaluate (generate) a truthy value iff both operands are truthy
* `||`: Boolean OR operator.
* `!`: Boolean NOT operator
```js
if ((x === 0 && y === 0) || !(z === 0)) {
// x and y are both zero or z is non-zero
}
```
## 3.5 null and undefined
`null`
* Def: special value, indicating "absence of a value"
* `typeof(null)` return `"object"`; So it means `null` is a special object, with value "no object".
* `null` is the sole member of this own type.
* It indicate "no value" for data type like number, strings and objects.
* similar in other language: `NULL` in C++
`undefined`
* Def: a deeper kind of absence, it's the value of variables that have not been initialized
* When query the value of an object project property or array element that **does not exist or not initilized**, return `undefined`
* It's predefined global constant, that's initilzed with value `undefined`
* `typeof(undefined)` return `"undefined"`, hence it's a special type
`null` similar as `undefined`
* both can use interchangeably.
* **equality operator `==`** will evalute them to be equal; **strict equality operator`===`** can distringuish them
* Both are falsy values
* Both of them have no property/methods
* visiting property/methods using `.` or `[]` returns `TypeError`
`null` different from `undefined` (by author)
* `undefined`: a system-level, unexpected or error like absence of value
* `null`: program-level, normal, or expected absence of value.
* Prefer to be assigned to variable or passed as return
## 3.6 Symbols
Prerequisite knowledge: JS's Object type is an unordered collection of properties, each property is a name/value pair.
Before ES6, property name are strings. Since ES6, **symbols** can also be used as **property name of an object**.
```js
let strname = "string name"; // A string to use as a property name
let symname = Symbol("propname"); // A Symbol to use as a property name
typeof strname // => "string": strname is a string
typeof symname // => "symbol": symname is a symbol
let o = {}; // Create a new object
o[strname] = 1; // Define a property with a string name
o[symname] = 2; // Define a property with a Symbol name
o[strname] // => 1: access the string-named property
o[symname] // => 2: access the symbol-named property
```
How to obtain a Symbol value:
* Symbol type does not have a literal syntax. (e.g. char used for string literal syntax)
* Use `Symbol()` function to obtain Symbol value as shown above.
* Syntax e.g.: `let variable_name = Symbol("property_name")`
How to use Symbol value:
* Use a symbol value as a property name to add a new property to an object.
* `Symbol()` function never return same (symbol) value, even given same string (`"property_name"`). So no worry to overwrite original property in Object.
Symbol value related functions:
* `Symbol()`: used to create symbol value
* `s.toString()`: return string used as argument when creating the value
* Note: two different symbol value can have same string
* `Symbol.for()`: used to search symbol value with given string
* JS defines a global Symbol registry
* If no Symbol are associated with that string, a new one is created&returned.
```js
let s = Symbol("sym_x");
s.toString() // => "Symbol(sym_x)"
```
```js
let s = Symbol.for("shared");
let t = Symbol.for("shared");
s === t // => true
s.toString() // => "Symbol(shared)"
Symbol.keyFor(t) // => "shared"
```
## 3.7 The Global Object
## 3.8 Immutable Primitive Values and Mutable Object References
## 3.9 Type Conversions
### 3.9.1 Conversions and Equality
### 3.9.2 Explicit Conversions
### 3.9.3 Objbect to Primitive Conversions
## 3.10 Variable Declaration and Assignment
### 3.10.1 Declarations with `let` and `const`
### 3.10.2 Variable Declarations with `var`
### 3.10.3 Destructuring Assignment