###### tags: `JavaScript` `基本運算` `邏輯運算` `短路特性` `位元運算` `位移運算` `object` `array`
# JS101 筆記
## Chrome debugger
在程式碼中打進 `debugger` 然後放進 chrome 的 developer tool 裡面,程式就會停在 `debugger` 那一行,然後就可以在 source 裡一行一行檢視。
另外如果我們在 souces 裡點一下數字就可以設下中斷點,也可以幫助debug。
## console.log
// 參考[《你所不知道的JS:導讀,型別與文法》](https://hackmd.io/s/B1TQ7_F64)
|語法|用途|
|:------:|:------|
| console.log(b)|在控制台 log 進資料(可印出內容)|
1. `log(b)`是一個 call function
- 把 b 這個變數的值交給被 call 的 funcion(在這裡是`log`)
- 也就是這裡是 log (取) b 這個變數的值的意思
2. `console.` 是一個 object reference(物件參考),參考到 `log(..) ` 所在的物件。
- 其中,`.`是一個運算子
- 也用來進行物件特性(object properties)的存取
## 運算子
// 參考《你所不知道的JS:導讀,型別與文法》
運算子分為以下幾類:
- assign
- `=`
- math
- `+`, `-`,`*`,`/`,`%`
- 複合指定
- `+=`, `-=`, etc.
- 遞增或遞減
- `++`, `--`
- object properties 的存取
- `.`
- 相等性
- `==`, `===`,`!=`,`!==`
- 比較
- `<`, `>`,`<=`, `>=`
- 邏輯
- `&&`(and) , `\\` (or), `!`(not)
## value and type
// 參考[《你所不知道的JS:導讀,型別與文法》](https://hackmd.io/s/B1TQ7_F64)
- number //42
- string //"42"
- boolean // ture, false
- array
- function
- object
### Type coercion
//參考[Type coercion](https://www.freecodecamp.org/news/js-type-coercion-explained-27ba3d9a2839/)
- explicit type coercion (明確的強制轉型)
- 又叫做 type casting
- 用內建函式轉型 coerce
- 由寫程式的人要求執行轉型
- 如 `Number(value)`
- implicit type coercion (隱含的強制轉型)
- JavaScript 自己進行 coerce
---
## 基本運算( math 和遞增、遞減)
|語法|用途|用例|注意點|
|:------:|:------:|:------|:----|
|+|加號|1 + 2 // 3|前後空格|
|-|減號|3 - 2 // 1|前後空格|
|* |乘號|2 * 3 // 6|前後空格|
|/|除號|4 / 2 // 2|前後空格|
|%|取餘數|10 % 3 // 1|前後空格|
|++|遞增|i++|==eslint 不接受==<br/> i++ 會先跑完整句才加, ++i 會先加完再跑整句|
|--|遞減|i++|==eslint 不接受==<br/> i-- 會先跑完整句才減, --i 會先減完再跑整句|
## 邏輯運算
|語法|用途|用例|
|:------:|:------:|:------|
| pipe * 2 | or|ture pipe * 2 false // ture<br/>* 這裡不支援pipe 符號|
|&&|and|ture && false // false|
|!|not|!ture // false<br/>!false // ture
### turth table
|A|B|A && B|A or B|!A
|:------:|:------:|:------:|:----:|:---:|
|ture|ture|ture|ture|false|
|ture|false|false|ture|fals|
|false|ture|false|ture|ture|
|false|false|false|false|ture|
### 邏輯運算短路特性
- 跑到有結果就會回傳
- 最後跑到哪一個就回傳那一個
|輸入|回傳|解釋|
|:------:|:------:|:------|
|3 or 10 | 3|在跑到 3 時已確定是 ture,所以直接回傳 3 |
|false or 10 |10|跑到 10 才確認是 ture,所以回傳 10|
|0 or false| 10 | 0 可以就當作是 false |
|3 && 10 |10| 在跑到 10 時才確定是 ture,所以回傳 10|
|false && 10 |false| 跑到 false 就確定是 false 所以回傳 false|
小筆記
//可以直接在 CLI 輸入 node 寫程式
## 位元運算
### 位移運算 `<<` 和 `>>`
把用二進制系統儲存的數據整個往左或往右移一位
|輸入|輸出|
|:------:|:------|
|10 << 1| 20|
|1 << 10 |1024|
* 在二進制整個數據往左移`>>`一位其實會使數據乘以 2
* 反之,如果是往右移 `<<`,則會除以2(有小數的部分會被消失不會進位)
* 如果位移的位元太多,會有 overflow 的問題
### 位元運算
1. 先把東西變成二進位
2. 對每一個位元運算
在 JavaScript 中
|語法|用途|輸入|輸出|二進位|
|:------:|:------:|:------:|:----:|:----:|
|&|and|10&15|10|1010 &<br/> 1111 ==<br/>1010|
|pipe|or|10 or 15|15| 1010 &<br/>1111== <br/>1111|
|^|xor|2 ^ 4|6|1010 &<br/>1111 ==<br/>0101|
|!|not|!15|-16|...00001111<br/>...1111110000|
* xor: 兩個東西一樣 -> 回傳 0 <br/> 兩個東西不一樣 -> 回傳 1
#### 用位元運算判斷奇偶數
|輸入|輸出|理由|推論
:------:|:------:|:----:|:----:|
|A & 1| 0| A 的最後一個位元是 0|A 是偶數|
|A & 1 | 1 |A 的最後一個位元是 1| A 是奇數|
### 變數
- 宣告變數
|statement |用法|說明|
|:------:|:------:|:----|
|var|宣告變數|ES5以前的舊用法會有[覆蓋和洩漏的問題](https://medium.com/@totoroLiu/javascript-var-let-const-%E5%B7%AE%E7%95%B0-e3d930521230)|
|let|宣告變數|ES6之後的語法|
|const|宣告常數|建議命名全大寫<br/>宣告之後就不會再被重新賦值|
- 如果宣告變數之後沒有賦值,變數就數會是 undefine
- 如果 log 的對象沒有被宣告,就會出現 Not define 警告
- 變數命名
- 最常見:駝峰式 newFunction
- 不合法:
- 用數字開頭
- 和內建函數、保留字同名
- 盡量用語意化的詞
- 讓後面的自己看得懂
### 變數型態
- 型態
- primitive
- number //42
- string //"42", '42'
- boolean // ture, false
- object
- array
- object
- null -- 這是一個Javascript 歷史久遠的 bug
- function
- undefine
- 查看型態
- 用內建函式`typeOf`
- 像是 `console.log(typeOf "32") // string `
### Object
- a computed value(複合值)
- 持有一些 properties(特性;具名的位置)
- 格式:
```
obj = {
key1 : value1,
key2 : value2
}
```
- 存取物件可以使用兩種方式:
- dot notatation
- 用 `obj.property`運算子存取 property
- bracket notation
- 用 `obj[property]`存取 property
- property 裡面放 array, object, function 都可以,放什麼都可以
#### array
- object 的子項目
- 可以想像成是以 index 取名的object
- 只能存相似的資料
- 內建函式
|語法|說明|
|:----:|:----|
|.length|陣列長度|
|.push|把 value 放到陣列最後一項|
## 變數運算
- 注意 type 問題
- 例如 `number + string` 時,`number` 會被 coerce 成 `string`
- 可以用兩種內建 function 強制把`srtring` 轉型成 `number`
- Number() //轉型為數字
- parseInt(number, 10) //逗號後面的數字是進位數(10進位)
- 浮點數誤差
- 電腦沒辦法把小數存得很精準
- 所以會發生 0.1 + 0.2 == 0.3 出來是 false 的狀況
## 相等性
// 參考[《你所不知道的JS:導讀,型別與文法》](https://hackmd.io/s/B1TQ7_F64)
JS 的 4 個 equality operators:
|符號|說明|
|:---:|:---|
|`==`|允許 implicit coercion 的相等性檢查|
|`===`|不允許 implicit coercion 的相等性檢查|
|`!=`|允許 implicit coercion 的不等性檢查|
|`!==`|不允許 implicit coercion 的相等性檢查|
//[Equality comparisons and sameness](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness)
// [ES5 規格第11.9.3節](http://ecma-international.org/ecma-262/5.1/#sec-11.9.3)相關implicit coercion 轉換優先順序 :
**The Abstract Equality Comparison Algorithm**
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
1. If Type(x) is the same as Type(y), then
1. If Type(x) is Undefined, return true.
2. If Type(x) is Null, return true.
3. If Type(x) is Number, then
1. If x is NaN, return false.
2. If y is NaN, return false.
3. If x is the same Number value as y, return true.
4. If x is +0 and y is −0, return true.
5. If x is −0 and y is +0, return true.
6. Return false.
4. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.
5. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
6. Return true if x and y refer to the same object. Otherwise, return false.
2. If x is null and y is undefined, return true.
3. If x is undefined and y is null, return true.
4. If Type(x) is Number and Type(y) is String,<br/>return the result of the comparison x == ToNumber(y).
5. If Type(x) is String and Type(y) is Number,<br/>return the result of the comparison ToNumber(x) == y.
6. If Type(x) is Boolean,<br/>return the result of the comparison ToNumber(x) == y.
7. If Type(y) is Boolean, <br/>return the result of the comparison x == ToNumber(y).
8. If Type(x) is either String or Number and Type(y) is Object,<br/>return the result of the comparison x == ToPrimitive(y).
9. If Type(x) is Object and Type(y) is either String or Number,<br/>return the result of the comparison ToPrimitive(x) == y.
10. Return false.
## Conditionals 條件式
### if/else statement
syntax:
```javascript=
if(conditional){
statement;
} else {
statement;
}
```
### switch case
syntax:
```javascript=
switch(varibleName) {
case 1:
statement
break
case 2:
statement
break
case 3:
statement
break
}
```
### ternary 三元運算子
syntax:
```javascript=
condition ? trueAnswer : wrongAnswer
```
範例:
```javascript=
var score = 60
var message = ''
message = score >= 60 ? 'pass' : 'fail'
```
## 迴圈
### do while
syntax:
```javascript=
do{
statement;
} while (conditional)
```
- continue 直接跳到下一圈(細節待補)
- break 跳出迴圈(細節待補)
### while 迴圈
```javascript=
while (conditional){
statement;
}
```
- do..while 和 while 差別在於
- while 會先做 conditional test 才進入第一次 iteration
- do..while 則會先執行第一次 iteration 才會進行 conditional test
### for
```javascript=
for(conditional){
statement;
}
```
例如:
```javascript=
for(var i = 0; i <= 9; i ++){
console.log(i);
}
//0 1 2 3 4 5 6 7 8 9
```
## function 函數
// 部分參考[《你所不知道的JS:導讀,型別與文法》](https://hackmd.io/s/B1TQ7_F64)
- 可重複使用的一個具名片段
- 也可以用來將相關的程式碼組織成具名的集合
- 可以藉由名稱來 call function
- call function 時要包含`()`
- 例: `console.log(functionName())`
- 不然就會印出他是一個 function
- 函式參數命名時盡量用有語意的字當參數增加可讀性
- 需要時可用 return 來回傳值
- 可以傳任何東西,包含物件
- 注意 return 後面不可以空白,不然會是 undefine
### anonymous function 匿名函式
- function 的參數也可以是一個 function
例:
```javascript=
function transform(arr,transformFunction){
let result = []
for(var i = 0; i < arr.length; i += 1){
result .push(transformFunction(arr[i]))
}
return result
}
console.log(
transform([1, 2, 3], function(x){
return x * 2
})
)
```
- 此時的 transformFunction 就是一個 anonymous function 匿名函式
### Parameter (參數)和 argument (引數)
```javascript=
function transform(arr,transformFunction)
transform([1, 2, 3], function(x){
return x * 2}
```
這裡的 `arr` 就是 parameter (參數), `[1, 2, 3], function(x)`就是 arguments (引數)
- 可以用 `console.log(arguments[0])`來 log 出第 0 個argument
- arguments 是一個 object 但是是一個 Array-like 的物件
### function 傳參數機制
- 用 dot notation 的時候會改到外面的
### return
- 不需要知道結果的
- 就不需要 return
- call function 時電腦不會得到回傳值
- 此時 return value 等於 undefine
- 會需要知道結果的
- 需要 return
- 在 function 中,電腦一遇到 return 就會立刻回傳,然後跳出function,所以在 return 後面的程式碼就不會被執行。
## Number 內建函式
// 待補
## string 內建函式
// 待補
## Immutable values
- 除了 object(包含 array) 之外,無法用 property accessor 如 dot notation 來改變變數的value。
- 需要用 `=` 來重新賦值才會被存下來
- 反之,在 object 裡用內建函式的 dot notation 進行操作,是會改到 property 的內容的