###### 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 的內容的