# 嬿媜 q1~q5_code review
### q1
#### playMovieMessage 命名
改為 IsPlayMovie 或 showMovieStatus?
### verify
#### IsPositiveInteger 命名
命名叫 IsPositiveInteger 是正整數,但是 0 不是正整數
```javascript!
export function IsPositiveInteger(input){
if(Number(input) < 0){
throw new Error('請輸入正整數^^');
}
}
```
#### ==符號有沒有擋到要確認一下==
### q2
宣告的 function 可以提出去外面,比較好閱讀。
可以再看一下巢狀要怎麼改。
### q3
#### calculateTicketPrice 命名
改為 GetTicketPriceByAge?
#### calculateTicketPrice
確定不會動的東西都用 const 先宣告,然後再修改其他情況。
```javascript!
// 原本寫法
export function calculateTicketPrice(userInput) {
let ticketPrice = 400;
if (userInput <= 6 || userInput >= 65) {
ticketPrice = ticketPrice * 0.5;
return `您的票價為:${ticketPrice} 元`;
} else {
return `您的票價為:${ticketPrice} 元`;
}
}
// 可以改為
export function calculateTicketPrice(userInput) {
const originalPrice = 400;
const discount = 0.5;
let ticketPrice;
if (userInput <= 6 || userInput >= 65) {
ticketPrice = ticketPrice * discount;
return `您的票價為:${ticketPrice} 元`;
} else {
ticketPrice = originalPrice;
return `您的票價為:${ticketPrice} 元`;
}
}
```
### q4
#### 驗證放一起
```javascript!
if(Number(userInput) === 0) {
console.log(`請輸入比 0 大的數字^^`);
main();
} else {
...
}
// 這個 0 的可以搬到後面的驗證一起
```
#### 讓 let i = 0 always 從 0 開始
通常不會改這個初始值
### test 現在是算式和總和分開測
不知道最終 console.log() 出來的東西是不是你想要的,可以放在一起測,測一整個 main
### 推薦看
array.reduce
Code Completed Ch11
# 季芳 q1~q5_code review
### q1
#### 1. 用 let 的用意?後面會對這個重新賦值嗎?
```javascript!
let playMovieMessage = playMovie(userInput);
```
季芳目前都是 const 用到底,如果變數要重新賦值才會改成 let。
#### 2. 知道rl是非同步嗎?
- 還有另一個套件,同步的: [heapwolf/prompt-sync: a synchronous prompt for node.js](https://github.com/heapwolf/prompt-sync),會等使用者輸入之後才會做下一步。
#### 3. 命名:大駝峰小駝峰
目前看都寫小駝峰,但 verify.js 裡面的`Is…`是大駝峰,命名時大小駝峰選一個用就好。
#### 4. `checkInputValidity`
這個 function 放在 verify 位置有點奇怪。
目前 verify 大多放獨立驗證的 function,`checkInputValidity`更像是容器在對內容作抽換。
可以看一下 [Jade](https://gitlab.com/dwatow/j1/-/blob/jade/Jade/common_module/validators.js) 寫的驗證。
#### 5. 沒驗到科學記號e
`1e01`
目前是從**使用者輸入**去驗。
還有一種驗法是:只能輸入什麼,最後一個用驗證用正則擋。
### q1 test
從執行結果看,執行結果沒有被描述出來。
Chirs 有提過:測試可能會給不懂程式的人看,假設這裡是給業主看的。
單從這邊的描述看不出測完的輸出結果,只看出有通過,但通過的結果是什麼不知道。這樣不會知道有沒有符合功能的需求。
- 可以用`describe` 當作容器把內容整理一下。 [Globals · Jest](https://jestjs.io/docs/api#describename-fn)
可以參考 [季芳](https://gitlab.com/-/ide/project/dwatow/j1/edit/FangLee/-/01/Q1module.test.js) 的,使用 describe 看看
```javascript!
import { Q1 } from "./Q1module.js";
describe("Q1:好想電影院規定除非完全沒有客人買票,否則就算只有一位顧客也照常播放電影,讓使用者輸入客人的人數,並用「!」判斷人數,不為零顯示「照常播放電影」。", () => {
test(`輸入"10",會輸出"照常播放電影"`, () => {
expect(Q1("10")).toBe("照常播放電影");
});
test(`輸入"0"會輸出"不播放電影"`, () => {
expect(Q1("0")).toBe("不播放電影");
});
});
describe("測試 Q1 不會輸出", () => {
test(`輸入"10",不會輸出"不播放電影"`, () => {
expect(Q1("10")).not.toBe("不播放電影");
});
test(`輸入"0",不會輸出"照常播放電影"`, () => {
expect(Q1("0")).not.toBe("照常播放電影");
});
});
describe("測試 Q1 以下都會拋出異常", () => {
test("無輸入", () => {
expect(() => Q1("")).toThrow();
});
test("輸入空格", () => {
expect(() => Q1(" ")).toThrow();
});
test("輸入+0", () => {
expect(() => Q1("+0")).toThrow();
});
test("輸入-0", () => {
expect(() => Q1("-0")).toThrow();
});
test("輸入0.5", () => {
expect(() => Q1("0.5")).toThrow();
});
test("輸入-5", () => {
expect(() => Q1("-5")).toThrow();
});
test("輸入中文", () => {
expect(() => Q1("中文")).toThrow();
});
test("輸入english", () => {
expect(() => Q1("english")).toThrow();
});
});
```
### q2
1. 主程式裡面兩個問題有點巢狀 *Callback Hell*,想一下要怎麼把第二題提出來。
- 第一題的輸入傳到第二題
2. 可以安裝 [Code Spell Checker - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker),會幫你檢查拼錯字(藍色底線)。
3. 同第一題使用 let 宣告的原因
4. 驗證完沒有轉型
### q3
1. 驗證完沒有轉型
2. calculateTicketPrice
```javascript!
// before
export function calculateTicketPrice(userInput) {
let ticketPrice = 400;
if (userInput <= 6 || userInput >= 65) {
ticketPrice = ticketPrice * 0.5; // 這裡會直接改到ticketPrice本身,ticketPrice會變成200
return `您的票價為:${ticketPrice} 元`;
} else {
return `您的票價為:${ticketPrice} 元`;
}
}
// after
export function calculateTicketPrice(userInput) {
const ticketPrice = 400;
if (userInput <= 6 || userInput >= 65) {
return `您的票價為:${ticketPrice * 0.5} 元`;
// 這樣ticketPrice還是400
} else {
return `您的票價為:${ticketPrice} 元`;
}
}
```
### q4
#### 1. `Number(userInput) === 0` 應該也是在做驗證吧?
這個可以收在`checkInputValidity`裡面,另外提到外面用if/else處理的原因是?
#### 2. 驗證完沒有轉型
#### 3. createFormula:`const n = input;`
這一行的用意是什麼?不能直接拿 input 去寫嗎?
通常不會用單一字母`n`來命名,也不會用簡寫。
#### 4. gstSum:結構很巢狀
不好讀:function 包 function,然後又if/else裡面包if/else,可以想一下怎麼拆成好讀一點的結構。
```javascript!
// 原本
function accumulate(currentInput, originalTotal) {
let currentTotal = originalTotal;
let currentValue = Number(currentInput);
if (currentValue === 1) {
currentTotal = currentTotal + currentValue;
} else {
if (currentValue % 2 === 0) {
currentTotal = currentTotal + currentValue;
} else {
currentTotal = currentTotal - currentValue;
}
return accumulate(currentValue - 1, currentTotal); // 要寫 return 因為要把 total 的值傳給下一個呼叫的自己
}
return currentTotal;
}
export function getSum(input) {
const total = accumulate(input, 0);
return total;
}
```
```javascript!
// 改寫
function accumulateSum(currentNumber, runningTotal) {
const isMinimumValue = currentNumber === 1;
if (isMinimumValue) {
return runningTotal + currentNumber;
}
const updatedTotal = getUpdatedTotal(currentNumber, runningTotal);
return accumulateSum(currentNumber - 1, updatedTotal);
}
function getUpdatedTotal(number, total) {
const currentNumberIsEven = number % 2 === 0;
if(currentNumberIsEven) {
return total + number;
}
return total - number;
}
export function getSum(number) {
const sumResult = accumulateSum(number, 0);
return sumResult;
}
```
### q5
#### 1. umleven、umlevenFormula
這兩個 function 裡面的內容看起來是重複的,可以想一下怎麼把重用的部分抽出來。
```
```
- 如果對迴圈練熟了,可以嘗試使用array method
### 推薦看
array method
# 阿傑 q1~q5_code review
### rl
```javascript!
import { createInterface } from 'readline';
const rl = createInterface({
input: process.stdin,
output: process.stdout
});
export { rl }; // 可以不用包 {},因為沒有要做其他事情
```
### verify
```javascript!
export function IsNotEmpty(input) {
if (!(String(input).trim().length > 0)) {
throw new Error('請輸入東西^^');
}
}
// rl 拿到其實就是 String 了,不用轉
export function IsNotEmpty(input) {
if (!(input).trim().length > 0)) {
throw new Error('請輸入東西^^');
}
}
// 可改為
export function IsNotEmpty(input) {
if (!(input).trim().length) {
throw new Error('請輸入東西^^');
}
}
```
怎麼知道自己在寫啥:)
```javascript!
!(input).trim().length
-> (input) 是拿到什麼?字串(假設我輸入3)
!(input).trim().length
-> !"3".trim().length
trim() 是什麼?會把前後空白都去掉的 funciton,會回傳字串
-> !"3".length
length 是什麼?會把字串轉為字串長度的 funciton,會回傳數字
-> !1
!1 會轉為布林值
1 會轉為 true
所以 !true 是 false
```
### 注意各處 let 考慮是否用 const
### isNaN / Number.isNaN
### Number.isInteger 看有沒有其他可以轉為數字的方式
[參考](https://dev.to/sanchithasr/7-ways-to-convert-a-string-to-number-in-javascript-4l)
###
<!-- # Chris q1~q5_code review -->
### q2
```javascript!
// 原本寫法
export function compareRemainders(firstNumber, secondNumber) {
if (firstNumber % 3 === secondNumber % 3) {
return `${firstNumber} 和 ${secondNumber} 餘數相同`;
} else {
return `${firstNumber} 和 ${secondNumber} 餘數不相同`;
}
}
// 可以改為
export function compareRemainders(firstNumber, secondNumber) {
const fistReminder = firstNumber % 3
const secondReminder = secondNumber % 3
if (fistReminder === secondReminder) {
return `${firstNumber} 和 ${secondNumber} 餘數相同`;
} else {
return `${firstNumber} 和 ${secondNumber} 餘數不相同`;
}
}
// 甚至可以讓這隻 function 只回傳布林值,讓主程式做印出
export function areRemindersEqual(firstNumber, secondNumber) {
const fistReminder = firstNumber % 3
const secondReminder = secondNumber % 3
return fistReminder === secondReminder
}
// main
const result = areRemindersEqual ? `${firstNumber} 和 ${secondNumber} 餘數相同` : `${firstNumber} 和 ${secondNumber} 餘數不相同`
console.log(result);
```
### 一個 function 只做一件事
### 讓 let i = 0 從 0 開始
如果要從一開始跑的可以這樣寫
```javascript!
for(let i = 0; i < n; i++) {
if(i === 0) {
continue;
}
...
}
```
### 驗證用一個 陣列跑forEach
```javascript!
export function checkInputValidity(input, moreValidation){
//basic
isNotEmpty(input);
isNumber(input);
isInteger(input);
isPositiveInteger(input);
//
moreValidation.forEach(validation => {
validation(input)
});
}
// 這樣呼叫
checkInputValidity(userInput, [isNotZero, OverFour, isEven]);
```
### 閉不閉包
```javascript!
// 原本
export function calculateSum(input) {
const total = accumulate(input);
return total;
function accumulate(currentInput) {
// side effect
let total = 0;
let currentValue = Number(currentInput);
if (currentValue === 1) {
total = total + currentValue;
console.log(total)
} else {
if (currentValue % 2 === 0) {
total = total + currentValue;
console.log(total)
} else {
total = total - currentValue;
console.log(total)
}
accumulate(currentValue - 1);
}
return total;
}
}
```
> 怕有副作用問題,所以改寫為變數就作用在自己的 function 裡面,再回傳出去
```javascript!
// 阿傑調整
export function calculateSum(input) {
const total = accumulate(input, 0);
return total;
function accumulate(currentInput, originalTotal) {
let currentTotal = originalTotal;
let currentValue = Number(currentInput);
if (currentValue === 1) {
currentTotal = currentTotal + currentValue;
} else {
if (currentValue % 2 === 0) {
currentTotal = currentTotal + currentValue;
} else {
currentTotal = currentTotal - currentValue;
}
return accumulate(currentValue - 1, currentTotal); // 要寫 return 因為要把 total 的值傳給下一個呼叫的自己
}
return currentTotal;
}
}
```
# Chris q1~q5_code review 🔥๛๛๛ก(ー̀ωー́ก )
### 到底要測什麼?測試應該如何訂定範圍、邊界
> 就是測:使用者輸入到輸出。
#### 現在我 q5 測的是:算式測一個,答案測一個
```javascript!
但是其實我們要測的是:"輸入" 印出 "算式=答案" >> 這一整串
原本測的方式
輸入 4
算式對,輸出 2*4,答案也對,輸出 8
但其實介面會不會是 2*4 8 還是 2*4 = 8
這你不會知道,測試不會噴錯
所以建議要"包起來一起測試"。
測輸入到輸出,都測到了,邏輯也跟介面分開(還是不太懂這句的意思)。
```
```javascript!
// 原本寫法
function main() {
rl.question('來算 2*4 + 4*6 + 6*8...+(n-2)*n 吧,請輸入一個 至少為 4 的偶數 n:', (userInput) => {
try {
checkInputValidity(userInput);
const umlevenSum = getUmlevenSum(Number(userInput));
const umlevenFormula = getUmlevenFormula(Number(userInput));
const result = `${umlevenFormula} = ${umlevenSum}`;
return result;
rl.close();
} catch (error) {
console.log(error.message);
main();
}
});
}
main();
// 改為
function main() {
rl.question('來算 2*4 + 4*6 + 6*8...+(n-2)*n 吧,請輸入一個 至少為 4 的偶數 n:', (userInput) => {
try {
const result = Q5(userInput);
console.log(result);
rl.close();
} catch (error) {
console.log(error.message);
main();
}
});
}
main();
// 就測 Q5 一整個就好
function Q5(userInput) {
checkInputValidity(userInput);
const umlevenSum = getUmlevenSum(Number(userInput));
const umlevenFormula = getUmlevenFormula(Number(userInput));
const result = `${umlevenFormula} = ${umlevenSum}`;
return result;
}
```
#### 要測輸入錯誤的時候會怎樣
```javascript!
// 測試例子至少測這些:
最小值
最小值-1
最大值 -> 要設一個值給他,錯誤會是我設定的 Error,想語言極限到哪裡
最大值+1
其他一堆不正常的輸入
```
### main()
export 拿掉
### verify
```javascript!
parseInteger.parseFloat -> parse 是解析 -> 解析什麼? 字串
isNotEmpty 你的命名有隱含是要放字串,所以裡面不一定要轉態
其實有兩派:
1. 丟什麼轉好再執行,避免 garbage in(丟數字會報錯的)
2. Chris 是不轉派的,自己寫自己用的,不做這件事就會跑比較快(少一個 stack)
寫容錯率很高 funciton 通常就是要給別人用的
```
### 對象
```javascript!
要想一下這個東西是要"給哪個對象用的"
舉例:我的驗證是我自己在用的,所以可以不用轉態,錯了再噴錯、自己看得到就好了
對象會影響你寫程式的錯誤處理機制!
```
### checkInputValidity 可以分兩段
```javascript!
export function checkInputValidity(input) {
isNotEmpty(input);
isStartsWithPlusOrMinusZero(input);
isNumber(input);
isInteger(input);
isPositiveInteger(input);
overFour(input);
isEven(input);
}
// 可以分為兩段,比較好區別驗證字串和驗證數字區
export function checkInputValidity(input) {
isNotEmpty(input);
isStartsWithPlusOrMinusZero(input);
isNumber(input);
isInteger(input);
isPositiveInteger(input);
overFour(input);
isEven(input);
}
```
### isNaN / Number.isNaN,我還是很混亂但總之先用 Number.isNaN
Number.isNaN
> The boolean value true if the given value is a number with value NaN. Otherwise, false.
如果給定值是值為 NaN 的數字,則布林值 true。否則為 false。
-> 只有數字型別的 NaN 丟的進來,其他都false
```javascript!
NaN 字串轉型為數字會是 NaN
Number("NaN") // NaN
-
Number.isNaN("NaN") // false
isNaN("NaN") // true
isNaN("NaN") // true
isNaN("ddd") // true
isNaN(Number("NaN")) // true
isNaN(Number("ddd")) // true
Number.isNaN("NaN") // false
Number.isNaN("ddd") // false
Number.isNaN(Number("NaN")) // true
Number.isNaN(Number("ddd")) // true
```
### 沒擋到
```javascript!
1e2
0x110
0xFE
因為要擋這些事情,所以要對數字型別非常清楚/有什麼表達方式
學進制轉換( 12轉8 啊,8轉10 啊,才有辦法知道這些事情)
```
### 科學記號補充
[IEEE 754](https://zh.wikipedia.org/zh-tw/IEEE_754)
[從 IEEE 754 標準來看為什麼浮點誤差是無法避免的](https://medium.com/starbugs/see-why-floating-point-error-can-not-be-avoided-from-ieee-754-809720b32175)
[BigInt](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/BigInt)
### 有意識の注意型別
```javascript!
寫 function 的時候注意"輸入和輸出各是什麼型別"
看完上面補充,可以知道為什麼JS會有這麼多數字型別
```
### 驗證輸入 0,我還是很混亂
```javascript!
// 輸入 0,不會跑錯誤訊息,
// 沒擋到 0,會直接跑 overFour()那段訊息
export function isPositiveInteger(input){
if(Number(input) < 0){
throw new Error('請輸入正整數^^');
}
}
export function overFour(input) {
if(Number(input) < 4) {
throw new Error('請輸入至少為 4 的數字^^');
}
}
// 改為:
export function isPositiveInteger(input){
if(Number(input) <= 0){
throw new Error('請輸入正整數^^');
}
}
```
### why 要寫 verify
> 引導熟悉型別的表達方式
### 不習慣這樣那樣讀
(使用多運算子時,會有運算先後順序的差別,不想去記)
```javascript!
const isMinimumSum = number === minimumValidNumber;
```
```javascript!
// 改寫 function(Chris 的習慣)
funciton isMinimumSum() {
return number === minimumValidNumber;
}
if(isMinimumSum()) {
...
}
// 或寫括號
const isMinimumSum = (number === minimumValidNumber);
```
### 哲學問題:轉態後才進 function / 進 function 才轉態
```javascript!
const finalTicketPrice = getTicketPriceByAge(Number(userInput));
or
function getTicketPriceByAge() {
const nUserInput = Number(userInput);
...
}
```
>判別標準:它是屬於誰的
>funciton 這一步,該煩惱它的型別嗎?
```javascript!
Chris 偏好轉型完再進 function,因為我就"認定裡面的東西一定是這個型別"
這個功能本身是假設好型別的,不要背負著轉態這件事情,我知道我要轉、而且我也轉好了!
```
### 匈牙利命名法
userInput 轉態完可以命名為 `nUserInput?`,[歷史看這裡](https://ithelp.ithome.com.tw/articles/10203983)
### return 要 return 一個 result 嗎
```javascript!
// 這個 result 像是中性的命名
const umlevenFormulaResult = `${getUmlevenFormula(number - 2)} + ${(number - 2)}*${number}`;
return umlevenFormulaResult;
// Chris 分享:
看到這串會先看到等號,咦,ok 他們相等,然後等號右邊和等號左邊名稱很像
左邊本就是右邊的結果,如果這個命名沒有特殊意義(這會有點像沒有命名),Chris 會直接寫 return。
如果是 array method 也不太會命名,就直接 return
除非超難讀,因為不會影響除錯閱讀速度,他只有要 return 沒有要做什麼處理
```
### q5 可以試試看用算式直接算答案
```javascript!
// 第一種:eval
eval('2*4 + 4*6') // 32
// 第二種:new Funciton
var f = new Function('return 2*4 + 4*6'); // 宣告
f(); // 32
```
### q1 - isPlayMovie
```javascript!
// 原本寫法像 over design 🥵
export function isPlayMovie(customerCount) {
const hasCustomer = (Number(customerCount) !== 0);
return hasCustomer;
}
export function showMovieStatus(isMoviePlaying) {
if (isMoviePlaying) {
return '今日營業中,放映電影:)';
} else {
return '今天休假,暫停放映:(';
}
}
```
```javascript!
// 簡潔寫法,回傳一個布林值
export function showMovieStatus(customerCount) {
const isMoviePlaying = (Number(customerCount) !== 0);
if (isMoviePlaying) {
return '今日營業中,放映電影:)';
} else {
return '今天休假,暫停放映:(';
}
}
```
### q1 - showMovieStatus
```
他不是狀態碼,可以命名為一個公告文字之類的
```
### q3 - getTicketPriceByAge 的 const 把變數都先列出來
```javascript!
// 原本寫法
export function getTicketPriceByAge(age) {
const originalTicketPrice = 400;
const maxChildAge = 6;
const minSeniorAge = 65;
const discountRate = 0.5;
const isChild = age <= maxChildAge;
const isSenior = minSeniorAge <= age;
if (isChild || isSenior) {
return `您的票價為:${originalTicketPrice} 元`;
} else {
const discountedTicketPrice = originalTicketPrice * discountRate;
return `您的票價為:${discountedTicketPrice} 元`;
}
}
```
```javascript!
// Chris 寫法
export function getTicketPriceByAge(age) {
const originalTicketPrice = 400;
const maxChildAge = 6;
const minSeniorAge = 65;
const discountRate = 0.5;
if (maxChildAge < age && age < minSeniorAge) {
return `您的票價為:${originalTicketPrice} 元`;
} else {
const discountedTicketPrice = originalTicketPrice * discountRate;
return `您的票價為:${discountedTicketPrice} 元`;
}
}
// 如果下次 maxChildAge < age && age < minSeniorAge 又有其他新的意思,再把它變成一個新的變數
```
### 德摩根定理
```javascript!
對符號做思考
! 先加上去邏輯顛倒
! 對符號乘法分配率對符號做顛倒邏輯
```
### 額外宣告變數好嗎
```javascript!
const finalTicketPrice = getTicketPriceByAge(Number(userInput));
console.log(finalTicketPrice);
v.s.
console.log(getTicketPriceByAge(Number(userInput)));
// 第一種寫法 - 會好讀、好維護、好測試結果,但是否有需要考慮額外宣告變數的內存?
//第二種寫法 - 可能在沒有那麼複雜的時候可以用
```
```javascript!
思考:左右兩邊有重複的命名,是否有必要,這會決定"這個變數有沒有存在價值",而不是這個寫法怎麼樣。
舉例:三角函數,爆算了一座山的高度
給左邊的結果命名:玉山高度 or 三角函數結果
前者就比較具有意義,後者就乾脆直接 return 算了
但結論是自己要看起來舒服。
而可讀是要"過自己那一關",是自己過幾個月回來也是要可讀。
```
### 熟悉度
```javascript!
要考慮到協作的人的熟悉度
你都寫柯里化,團隊的新手都來問你
其實可以寫簡單一點一般寫法,然後你可以做自己的事XD
```
### 看 code 的時候不要靠腦子的記憶,全部用眼睛看出來
```javascript!
可以試試看不靠記憶去讀,這樣才不會一直寫的東西都因為你知道,所以看得出來,但別人看不出來
```
### 哲學問題 - 檔案分類方式,不要為了分檔案分檔案
```javascript!
1. 你喜歡就好
2. 都嘗試看看選個好讀的
3. 方便除錯
但是之後你要選一個對自己來說"最簡單"的為優先(先簡單再好用)
不知道要選什麼,就隨便選一個方法,去體驗:為什麼要分開?分開是適合的嗎?之後不夠用,就知道另外一個好處是什麼了。
```
### 目前我的可以怎麼分檔
```javascript!
可以試試看用 verify 就好,每隻的 validation 不用分(放到Q5),Q5 拉出去
import { checkInputValidity } from './modules/validation.js';
import { getUmlevenSum, getUmlevenFormula } from './modules/umleven.js';
這兩個就會出現在 Q5
```
### 滿幾個月了,為什麼大家 J1 都寫超過一個月XD
```javascript!
不用把所有語法弄懂再繼續下去,趕快把它寫一寫
但重要的是:你的想法要跟語法一致!
-
function:
四種寫法可以就好(建構式、一般呼叫、method、立即執行)
忍者一和二以 ES6 為分水嶺(推忍者,其他都是輔助書)
型別:
盡量去認識就好,有遇到記得,有遇到記得,不用急著一次把他認識完
多的是機會,多的是認識這語法的機會~
認為覺得去認識測試,語意語法合在一起,時間拉長、熟悉度會提高,因為這是沒有標準答案的問題,需要時間去醞釀,語法就是看語法書學就好
鼓勵有問題馬上問,不用等看 code 的時候問即時問
記憶新鮮度降低,就不會覺得是痛點了,所以馬上問是最好的。
結論:速度是正常的,不用擔心。
```
### 要學哪個框架?
```javascript!
學框架重要的是學觀念。
(React 文件寫得比較好)
學哪一個都沒關係,會 Vue 也可以找 React 和 Angular 工作。
求職重要的是看你可不可以很快學一個東西。
```