--- title: Javascript description: 基本知識複習 img: alt: author: name: Jack.hu bio: img: tags: - Javascript --- # Javascript ### 一、特性 1. 弱型別語言 -> 語法簡潔 -> 易上手 2. 前後端皆可用 **(前端規格參考:ES6,後端NODEJS規格參考:CommonJS)** 3. 除了基本型別之外,萬物皆物件 4. prototype-based,非class-based ### 二、宣告及賦值 #### 宣告 > 需注意scope範圍(function、block) 1. var 2. let & const #### 基本賦值 1. = ### 三、基本型別(5大型別) > 型別資訊是在值,而非在變數。 1. string 2. number 3. boolean 4. undefined 5. null ```javascript= // 為什麼null的型別是object? -> 當初設計時的BUG typeof null // object // 注意NaN這個值的型別 typeof NaN // number ``` ### 四、物件型別 1. Array 2. Object ### 五、運算子 1. 型別為number,四則運算及比較運算較不會有問題,唯一需注意小數運算會有 **精準度問題**。 2. 型別為string,一些運算操作會導致值會進行 **隱性轉型**,需注意。 #### 四則運算 > 先乘除後加減,同數學運算規則。 1. \+ 2. \- 3. \* 4. \/ 5. \%(餘數運算) #### 字串運算 1. \+ 2. \- 3. \* 4. \/ #### 比較運算 > 進行比較時,會隱性透過原型方法(valueOf、toString)轉成基本型別後才能進行比較。 1. \> 2. \< 3. \== 4. \!= 5. \>= 6. \<= 7. **\===** 8. **\!==** #### 邏輯運算 > truthy、falsy vs true、false。 > 跟一般程式語言的true&false不太一樣 1. \&& 2. \|| 3. \! ```javascript= let a = 123; let b = "111"; let c = null; console.log(a && b); // 111 注意此例 console.log(a || b); // 123 console.log(c && a); // null console.log(a && c); // null console.log(c || a); // 123 Boolean("false") // ? Boolean("0") // ? Boolean("''") // ? ``` #### 位元運算 1. \& 2. \| 3. \^(XOR) 4. \~ 5. \>> 6. \<< #### 三元運算 1. ...? true: false ```javascript= // 條件? true -> 執行: false -> 執行; 1 === 2? console.log(true):console.log(false); // false ``` #### 其他運算 1. ... in ... ### 六、基本流程 1. if else 2. for 3. while 4. do while 5. switch ### 七、進階流程 1. for of vs for in ### 八、this 1. this會指向定義this所在位置的上層物件。 2. arrow func 沒有this,取決於parent scope的this。 #### 對象 1. function vs () => \{\} 2. constructor func 3. object ### 九、hoisting 1. 宣告變數提升 ```javascript= var x = 1; var doSomeThing = function(y) { console.log(x); // ? var x = 100; return x + y; }; console.log(doSomeThing(50)); // 150 console.log(x); // 1 ``` 2. 宣告函數提升 ```javascript= // case 1 square(2); // 4 function square(number) { return number * number; } // case 2 square(2); // TypeError: square is not a function var square = function (number) { return number * number; }; ``` ### 十、Scope Chain ```javascript= // scope chain 在函數被定義好後就被決定好。 var msg = "global." function outer() { var msg = "local." function inner() { return msg; } return inner; } var innerFunc = outer(); console.log(innerFunc); var result = innerFunc(); console.log( result ); // ? ``` ### 十一、Prototype #### function 1. call, apply 2. bind #### Obejct 1. valueOf 2. toString ### 十二、sync vs async #### callback hell #### Promise(ES6) #### async and await(ES7) 1. 在迴圈使用上原則上沒問題,但會有些例外,需注意。 ### 十三、其他 #### a++ vs ++a ```html= <h4>++在前</h4> <script> e = ++a + b; // ++a = a+1 = 11 and e = 11 + b = 31 document.write("e:", e, "<br />"); document.write("a:", a, "<br />"); </script> <h4>++在後</h4> <script> f = a++ + b; // f = a + b = 30 and a++ = a + 1 = 11 document.write("f:", f, "<br />"); document.write("a:", a, "<br />"); </script> ``` #### RegExp ```javascript= const multiCondiNotEmptyRegExp = new RegExp('_\\(condi,([0-9]+),([0-9]+),([0-9a-zA-Z -,/\'\.]+)\\)'); /* * handles _(condi,start,end,showStr) */ function multiCondiNotEmptyFormatter(questions, answers, questionOffset, templateString) { let result = templateString; console.log("multiCondiNotEmptyFormatter start ===========================\n"); console.log("result: " + result + "\n"); while (multiCondiNotEmptyRegExp,test(result)) { const [matchedStr, index1, index2, showStr] = multiCondiNotEmptyRegExp.exec(result); const start = parseInt(index1, 10) - questionOffset; // 不確定是否為整數型態,先轉換型態。 const end = parseInt(index2, 10) - questionOffset; // 不確定是否為整數型態,先轉換型態。 console.log("matchedStr: " + matchedStr + "\n"); console.log("index1: " + index1 + "\n"); console.log("index2: " + index2 + "\n"); console.log("showStr: " + showStr + "\n"); console.log("start: " + start + "\n"); console.log("end: " + end + "\n"); // 思考構想 我想要非連續數的判斷 我不要2-10這種 我要 2,4,6,5 const answerStart = answers[start]; console.log('answer: ' + answerStart + '\n'); console.log(typeof(answerStart)); console.log(answerStart); console.log(answerStart.length); // =========================================== let numArray = [] switch (answerStart) { for (let i in numArray) { case numArray[i]: if (numArray[i].length > 0) { insertTarget = showStr; }; break; }; }; result = _.replace(result, foundLiteral, insertTarget); }; console.log('\n->\n'); console.log('result: ' + result); console.log('\nnotEmptyFormatter end ==========================='); return result; } function locationOrientationFormatter(answers, locationIndex, templateString) { console.log(answers); console.log("+++++++++++++++++++++++++++++++++++++"); const locations = answers[locationIndex]; console.log(locations); // assume orientation is the next one const orientations = answers[locationIndex + 1]; console.log(orientations); // assume distances is the next one const distances = answers[locationIndex + 2]; console.log(distances); // * assume locations and orientations have same length const result = _.zip(orientations, locations, distances) .map(locationSet => `${locationSet[0]} ${locationSet[1]} ${locationSet[2]} cm`); return _.replace(templateString, '_(location,orientation)', '<i data-focus="loca">' + grammars.joinWordArray(result) + '</i>'); } ``` --- ###### tags: `Javascript`