Finished up to 3.10
parent
c88567c085
commit
3a9d9ffc7f
|
@ -598,16 +598,224 @@ function equalArrays(a, b) {
|
||||||
|
|
||||||
## 3.9 Type Conversions
|
## 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
|
### 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.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
|
## 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`
|
### 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`
|
### 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
|
### 3.10.3 Destructuring Assignment
|
Loading…
Reference in New Issue