Finished up to 3.10
parent
c88567c085
commit
3a9d9ffc7f
|
@ -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
|
Loading…
Reference in New Issue