Finished up to 3.10

master
Jason Zhu 2021-01-11 11:43:56 +11:00
parent c88567c085
commit 3a9d9ffc7f
1 changed files with 209 additions and 1 deletions

View File

@ -598,16 +598,224 @@ function equalArrays(a, b) {
## 3.9 Type Conversions
**Implicit Conversion**: JS can convert values to its required data type automatically
```js
10 + " objects" // => "10 objects": Number 10 converts to a string
"7" * "4" // => 28: both strings convert to numbers
let n = 1 - "x"; // n == NaN; string "x" can't convert to a number
n + " objects" // => "NaN objects": NaN converts to string "NaN"
```
* Primitive-to-primitive conversion: Refer to [JS primitive-to-primitive conversion table](https://riptutorial.com/javascript/example/16970/primitive-to-primitive-conversion-table) for details
* Object-to-primitive conversion: some more complicated
### 3.9.1 Conversions and Equality
Two equality operators used JS to test whether 2 values are equal:
* **strict equality operator**: `===`, two operands are not equal if they are not of same type
* **flexible equality operator**: `==`, JS can convert types
```js
null == undefined // => true: These two values are treated as equal.
"0" == 0 // => true: String converts to a number before comparing.
0 == false // => true: Boolean converts to number before comparing.
"0" == false // => true: Both operands convert to 0 before comparing!
```
§4.9.1 explain conversion performed by `==` operator
### 3.9.2 Explicit Conversions
### 3.9.3 Objbect to Primitive Conversions
Explicit conversion is needed for customized requirements.
#### Simplist explicit conversion
Using functions:
* `Boolean()`
* `Number()`
* `Boolean()`
```js
Number("3") // => 3
String(false) // => "false": Or use false.toString()
Boolean([]) // => true
```
Using `.toString()` method:
* All value (except `null` & `undefined`) has `toString()` method.
* Result is as same as `String()`
Legacy from the past: `Boolean`, and other functions can be used as constructor with `new`. It create **wrapper** object that behaves just like a primitive. Don't use it
#### Use some JS operators
* `+` or `-`: if one operand is string, it convert another to string
* `!`: first convert operand to a boolean, then negate/revert it.
```js
x + "" // => String(x)
+x // => Number(x)
x-0 // => Number(x)
!!x // => Boolean(x): Note double !
```
#### Formatting & Parsing number
Convert Number class object to string using `toString()`:
* which accept optional argument for radix (基数)
```js
let n = 17;
let binary = "0b" + n.toString(2); // binary == "0b10001"
let octal = "0o" + n.toString(8); // octal == "0o21"
let hex = "0x" + n.toString(16); // hex == "0x11"
```
Convert Number class object to string, with control over number of decimal places:
* `.toFixed()`: string with specified number of digits after the decimal point.
* `.toExponential()`: string in exponential notation; given specified number of digits after decimal point.
* `.toPrecision()`: string with number of significant digits you specify. (即有几个可见数位)
```js
let n = 123456.789;
n.toFixed(0) // => "123457"
n.toFixed(2) // => "123456.79"
n.toFixed(5) // => "123456.78900"
n.toExponential(1) // => "1.2e+5"
n.toExponential(3) // => "1.235e+5"
n.toPrecision(4) // => "1.235e+5"
n.toPrecision(7) // => "123456.8"
n.toPrecision(10) // => "123456.7890"
```
#### Parsing string to number
Problem of `Number()`:
* Only accept integer or floating-point
* Only worked for base-10 integers
* Does not allow trailing characters (string). e.g. `10blahblah`
Solution:
* `parseInt()`
* global function; parse only integers;
* if begin with "0x" or "0X", interpret it as hex
* Accept optional 2nd argument specifying radix
* `parseFloat()`
* global function; parse both integer and floating-point numbers;
Both `parseInt()` & `parseFloat()`:
* skip leading whitespace
* parse as many numeric characters as they can
* Ignore all following char
```js
parseInt("3 blind mice") // => 3
parseFloat(" 3.14 meters") // => 3.14
parseInt("-12.34") // => -12
parseInt("0xFF") // => 255
parseInt("0xff") // => 255
parseInt("-0XFF") // => -255
parseFloat(".1") // => 0.1
parseInt("0.1") // => 0
parseInt(".1") // => NaN: integers can't start with "."
parseFloat("$72.47") // => NaN: numbers can't start with "$"
parseInt("11", 2) // => 3: (1*2 + 1)
parseInt("ff", 16) // => 255: (15*16 + 15)
parseInt("zz", 36) // => 1295: (35*36 + 35)
parseInt("077", 8) // => 63: (7*8 + 7)
parseInt("077", 10) // => 77: (7*10 + 7)
```
### 3.9.3 Object to Primitive Conversions
JS has complicated rule to convert objects to primitive values.
TODO: finish this section
## 3.10 Variable Declaration and Assignment
Binding a name to a value = "assigning a value to a *variable*", variable's value can change as program runs.
Steps of using variable in JS:
1. **declare** variable using `let` `const` keywords (in ES6)
2. Use declared/initialized variable
### 3.10.1 Declarations with `let` and `const`
Declare variable in modern JS (ES6 and later):
* `let` keyword: e.g. `let i;`
* multi-variables supported: e.g. `let i, sum;`
* **Initialized** variable is recommanded: e.g. `let message = "hello";`
* Uninitilized variable's value is `undefined` until assigned with value.
Declare a constant using `const`:
* constant variable need initilization at the same time
* Their value cannot be changed ever, otherwise, cause `TypeError`
* Convention: constant are **capital letters**: e.g. `HTTP_NOT_FOUND`
```js
const H0 = 74; // Hubble constant (km/s/Mpc)
const C = 299792.458; // Speed of light in a vacuum (km/s)
const AU = 1.496E8; // Astronomical Unit: distance to the sun (km)
```
#### Variable and constant scope
Block scope (Same as in C/C++)
* Variable declared outside code blocks are **global variables**
#### Repeated declarations
* Declare multiple vars in a same scope with same name is **syntax error**
* It's not when it's in nested scope
```js
const x = 1; // Declare x as a global constant
if (x === 1) {
let x = 2; // Inside a block x can refer to a different value
console.log(x); // Prints 2
}
console.log(x); // Prints 1: we're back in the global scope now
let x = 3; // ERROR! Syntax error trying to re-declare x
```
#### Declarations and types
* In statically typed language (e.g. C/C++ or Java), variable declaration is to specify type of value
* No type associated with JS declaration. A JS variable can hold any type
```js
let i = 10;
i = "ten";
```
### 3.10.2 Variable Declarations with `var`
Before ES6
* Declare a variable using `var`
* No constant declaration
`var` syntax:
* similar as `let`
```js
var x;
var data = [], count = data.length;
for(var i = 0; i < count; i++) console.log(data[i]);
```
`var` vs. `let`:
* Scope of `var`: **Function scope**
* variables declared with `var` do not have (nested) block scope. The only scope they have is the function that containing them.
* Global variable using `var`:
* if `var` used outside of a function body, it declare a global variable
* Global variable declared with `var` are implemented as properties of the global object, which can be referenced using `globalThis`. e.g.
* in function, declare `var x = 2`; from program's view, it's same as `globalThis.x = 2`
* variable declared by `let` & `const` are not global object property
* `var` allows redeclare, due to function scope (instead of block scope)
* variable decalred with `var`, its declaration is lifted up (**hosted**) to top of enclosing function
* Refer to [Stack Overflow: What's the difference-between-using-let-and-var](https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var)
### 3.10.3 Destructuring Assignment