# 基礎
連結:<https://hackmd.io/@ntust/ncc-js-2>

---
## 講者
- 四資管四 徐孟辰
---
## 本次社課
* Hello, meow! - 10min
* 程式結構 - 5min
* 現代模式,`"use strict"` - 5min
* 變數 - 10min
* 資料型態 - 10min
* 型態轉換 - 10min
* 運算子 - 10min
* 比較 - 10min
* 互動:`alert`、`prompt`、`confirm` - 5min
* 條件運算子:`if` 和 `?` - 10min
* 邏輯運算子 - 10min
* 迴圈:`while` 和 `for` - 10min
* `"switch"` 陳述式 - 5min
* 函式 - 10min
* 函式表達式和箭頭
* JavaScript 的特別回顧
---
### Hello, meow!(PART 1)
* "script" 標籤
* 現代標記
* 外部腳本
* 小結
* 牛刀小試
---
#### "script" 標籤
執行:<https://plnkr.co/edit/2CU86jNny2zD7YYBXhVF?p=preview>
```htmlmixed=
<!DOCTYPE HTML>
<html>
<body>
<p>Before the script...</p>
<script>
alert( 'Hello, meow!' );
</script>
<p>...After the script.</p>
</body>
</html>
```
---
#### 現代標記
* type 屬性:`<script type=…>`
* language 屬性:`<script language=…>`
* 在腳本前後註解
```htmlmixed=
<script type="text/javascript"><!--
...
//--></script>
```
> 過時的
---
#### 外部腳本
```htmlmixed=
<script src="/path/to/script.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js"></script>
<script src="/js/script1.js"></script>
<script src="/js/script2.js"></script>
…
```
---
#### 外部腳本 - 注意
```htmlmixed=
<script src="file.js">
alert(1); // 由於 src 已被設置,內容會被忽略
</script>
<script src="file.js"></script>
<script>
alert(1); // 這裡會動
</script>
```
---
#### 小結
* 使用 `<script>` 標籤可以使用 JavaScript 的程式
* `type` 和 `language` 屬性是不必要的
* 可以插入外部文件的腳本
---
#### 牛刀小試
1. 顯示提醒
* 建立一個顯示訊息 `Meow!` 的頁面。
2. 使用外部腳本顯示提醒
* 承上題,並建立一個 `alert.js` 檔案。
---
### 程式結構(PART 2)
* 陳述(Statements)
* 分號(Semicolons)
* 註解(Comments)
---
#### 陳述(Statements)
```htmlmixed=
// 可以動,但不好讀
alert('Hello'); alert('Meow');
```
```htmlmixed=
alert('Hello');
alert('World');
```
---
#### 分號(Semicolons)
```htmlmixed=
alert('Hello')
alert('World')
```
<https://tc39.github.io/ecma262/#sec-automatic-semicolon-insertion>
```htmlmixed=
alert(3 +
1
+ 2);
```
---
#### 註解(Comments)
```htmlmixed=
// 註解可以獨立一行
alert('Hello');
alert('World'); // 註解也可以在陳述之後
```
```htmlmixed=
/* 當你需要寫很多行的時候
這是多行註解。
*/
alert('Hello');
alert('World');
```
```htmlmixed=
/* 註解程式碼
alert('Hello');
*/
alert('World');
```
沒辦法「**巢狀註解**」
---
### 現代模式,`"use strict"` (PART 3)
* `"use strict"`
* 瀏覽器控制台
* 總是使用 `"use strict"`
---
#### `"use strict"`
```javascript=
"use strict";
// 程式以現代模式運作
...
```
* 一定要放在 script 的第一行
* 一旦啟用無法取消
---
#### 瀏覽器控制台
```htmlmixed=
'use strict'; <按下 Shift+Enter 換行>
// ...your code
<按 Enter 運行>
```
更可靠的方法
```htmlmixed=
(function() {
'use strict';
// ...your code...
})()
```
---
#### 總是使用 `"use strict"`
1. 使用後會直接啟用
2. 會改變某些類別或模組的行為
3. 所有現代瀏覽器都支援
4. 後續所有程式都以嚴格模式(`"use strict"`)作為開頭,只有很少情況會有例外。
---
### 變數(PART 4)
* 一個變數
* 真實的比喻
* 變數命名
* 常數
* 正確表達
* 小結
* 牛刀小試
---
#### 一個變數
```javascript=
let message;
message = 'Hello!';
alert(message);
```
```javascript=
let user = 'John', age = 25, message = 'Hello';
let user = 'John';
let age = 25;
let message = 'Hello';
let user = 'John',
age = 25,
message = 'Hello';
let user = 'John'
, age = 25
, message = 'Hello';
```
---
#### 一個變數
過去的變數宣告用法 `var`
```javascript=
var message = 'Hello';
```
---
#### 真實的比喻
 
```javascript=
let message;
message = 'Hello!';
message = 'World!';
```
:information_source: Functional languages
---
#### 變數命名
```javascript=
let userName;
let test123;
let $ = 1;
let _ = 2;
let 1a;
let my-name;
```
* 大小寫
* 非拉丁文字 `let имя = 1;` `let 我 = 2;`
* 保留名
:information_source: `use strict` 的影響
```javascript=
num = 5
```
---
#### 常數
* 把 `let` 改成 `const`
* 無法變更
* 記得要大寫 `const PI = 3.1415926;` `const COLOR_RED = "#F00";`
---
#### 正確表達
* 寫人類看得懂的
* 盡量不要縮寫或用短名
* 簡潔有力避免通俗如:`data` `value`
* 遵照團隊規範
---
#### 小結
* `let`
* `var`
* `const`
---
#### 牛刀小試
* 使用變數
* 宣告兩個變數 `admin` 和 `name`
* 指定 "John" 到 `name`
* 把 `name` 的值複製給 `admin`
* 用 alert 顯示 `admin` 的值
* 正確命名
* 建一個變數存我們的星球 "地球",你應該怎麼取名
* 建一個變數存目前網站的訪客名稱 "John",你應該怎麼取名
* 常數大寫
* const birthday = '18.04.1982';
* const age = someCode(birthday);
---
### 資料型態(PART 5)
* 數字
* 字串
* 布林(邏輯類型)
* "null" 值
* "undefined" 值
* 物件(object)和符號(symbol)
* `typeof` 運算子
* 小結
* 牛刀小試
---
#### 數字
```javascript=
let n = 123;
n = 12.345;
```
* `Infinity`
* `NaN`
---
#### 字串
```javascript=
let str = "Hello";
let str2 = 'Single quotes are ok too';
let phrase = `can embed ${str}`;
// 多行字串
let str3 = `
One
Two
`
```
* 沒有 `char` 型態
---
#### 布林(邏輯類型)
```javascript=
let nameFieldChecked = true;
let ageFieldChecked = false;
let isGreater = 4 > 1;
alert( isGreater );
```
---
#### "null" 值
```javascript=
let age = null;
```
---
#### "undefined" 值
```javascript=
let x;
alert(x);
x = 123;
alert(x);
x = undefined;
alert(x);
```
---
#### 物件(object)和符號(symbol)
* `object` 是特殊的
* `symbol` 是對物件的唯一標示
---
#### `typeof` 運算子
兩種用法
1. typeof x
2. typeof(x)
```javascript=
typeof undefined
typeof 0
typeof true
typeof "foo"
typeof Symbol("id")
typeof Math
typeof null
typeof alert
```
---
#### 小結
* `number` 整數或浮點數...
* `string` 文符字
* `boolean` 給 `true` / `false` 使用
* `null` 未知的數值
* `undefined` 未指派
* `object` 更複雜的資料結構
* `symbol` 唯一標示符
typeof
* 兩種格式 `typeof x` `typeof(x)`
* `null` 的類型理論上不是 "object" 他是為了向下兼容產生的 bug
---
#### 牛刀小試
```javascript=
let name = "Ilya";
alert( `hello ${1}` );
alert( `hello ${"name"}` );
alert( `hello ${name}` );
```
---
### 型態轉換 (PART 6)
> 上次應該講到這
這裡暫且不討論 *物件* 的轉換
* 字串轉換
* 數字轉換
* 布林轉換
* 小結
* 牛刀小試
---
#### 字串轉換
```javascript=
let value = true;
alert(typeof value);
value = String(value);
alert(typeof value);
```
---
#### 數字轉換
```javascript=
alert( "6" / "2" );
```
```javascript=
let str = "123";
alert(typeof str);
let num = Number(str);
alert(typeof num);
```
---
#### 數字轉換
| 值 | 轉換後 |
| -------- | -------- |
| `undefined` | `Nan` |
| `null` | `0` |
| `true` / `false` | `1` / `0` |
| `string` | 把前後空白去掉後,<br />若字串是空的則變 `0` ;<br />純數字則直接轉;<br />否則變 `NaN`。|
* `+` 運算子
---
#### 布林轉換
```javascript=
alert( Boolean(1) );
alert( Boolean(0) );
alert( Boolean("hello") );
alert( Boolean("") );
```
* `0` 和 `" "` 都是 `true`
---
#### 小結
* String(value)
* Number(value)
* Boolean(value)
* 還有一些運算子可以轉換型態
---
#### 牛刀小試
```javascript=
"" + 1 + 0
"" - 1 + 0
true + false
6 / "3"
"2" * "3"
4 + 5 + "px"
"$" + 4 + 5
"4" - 2
"4px" - 2
7 / 0
" -9 " + 5
" -9 " - 5
null + 1
undefined + 1
" \t \n" - 2
```
---
### 運算子(PART 7)
* 術語:"unary", "binary", "operand"
* 字串連接,二元(binary)+
* 數字連接,一元(unary)+
* 運算子優先序
* 指派(Assignment)`=`
* 剩餘(Remainder)`%`
* 指數(Exponentiation)`**`
* Increment / decrement
* 位元運算子
* Modify-in-place
* 逗號(Comma)
* 牛刀小試
---
#### 術語:"unary", "binary", "operand"
```javascript=
let x = 1;
x = -x;
alert( x );
let x = 1, y = 3;
alert( y - x );
```
---
#### 字串連接,二元(binary)+
```javascript=
let s = "my" + "string";
alert(s);
alert(2 + 2 + '1' ); // "41" and not "221"
```
---
#### 數字連接,一元(unary)+
```javascript=
let x = 1;
alert( +x );
let y = -2;
alert( +y );
alert( +true );
alert( +"" );
```
```javascript=
let apples = "2";
let oranges = "3";
alert( apples + oranges );
alert( +apples + +oranges );
```
---
#### 運算子優先序
<https://developer.mozilla.org/en/JavaScript/Reference/operators/operator_precedence>

---
#### 指派(Assignment)`=`
```javascript=
let a, b, c;
a = b = c = 2 + 2;
alert( a );
alert( b );
alert( c );
```
* `=` 運算子會回傳數值
```javascript=
let a = 1;
let b = 2;
let c = 3 - (a = b + 1);
alert( a );
alert( c );
```
---
#### 剩餘(Remainder)`%`
* `a % b` 的結果是 a 除 b 之後的剩餘
* 與 *百分比* 無關
```javascript=
alert( 5 % 2 );
alert( 8 % 3 );
alert( 6 % 3 );
```
---
#### 指數(Exponentiation)`**`
* aka 次方
```javascript=
alert( 2 ** 2 );
alert( 2 ** 3 );
alert( 2 ** 4 );
alert( 4 ** (1/2) );
alert( 8 ** (1/3) );
```
---
#### Increment / decrement
* `++` 可以讓 *變數* *加* 1
* `--` 可以讓 *變數* *減* 1
```javascript=
let counter = 0;
alert( ++counter );
let counter2 = 0;
alert( counter2++ );
```
```javascript=
let counter = 1;
alert( 2 * ++counter );
let counter2 = 1;
alert( 2 * counter2++ );
let counter3 = 1;
alert( 2 * counter3 );
counter3++;
```
#### 位元運算子
> 用 32-bit 整數,它不在 JS 的規範中,但大多程式語言都有
* AND ( `&` )
* OR ( `|` )
* XOR ( `^` )
* NOT ( `~` )
* LEFT SHIFT ( `<<` )
* RIGHT SHIFT ( `>>` )
* ZERO-FILL RIGHT SHIFT ( `>>>` )
<https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators>
---
#### Modify-in-place
```javascript=
let n = 2;
n += 5;
n *= 2;
alert( n );
```
```javascript=
let n = 2;
n *= 3 + 5;
alert( n );
```
* 賦值運算優先較低
---
#### 逗號(Comma)
> 它也可以是運算子,最特殊,且優先權非常低
```javascript=
let a = (1 + 2, 3 + 4);
alert( a );
```
```javascript=
for (a = 1, b = 3, c = a * b; a < 10; a++) {
...
}
```
---
#### 牛刀小試
```javascript=
let a = 1, b = 1;
let c = ++a;
let d = b++;
```
```javascript=
let a = 2;
let x = 1 + (a *= 2);
```
```javascript=
let x = y = 0;
+x++ + ++y; // output? x = ? y = ?
```
---
### 比較(PART 8)
* 運算結果是布林
* 字串比較
* 不同型態比較
* 嚴格相等比較
* `null` 和 `undefined` 的比較
* 小結
* 牛刀小試
---
#### 運算結果是布林
```javascript=
alert( 2 > 1 );
alert( 2 == 1 );
alert( 2 != 1 );
let result = 5 > 4;
alert( result );
```
---
#### 字串比較
```javascript=
alert( 'Z' > 'A' );
alert( 'Glow' > 'Glee' );
alert( 'Bee' > 'Be' );
```
> 並非嚴格的按照字母順序,實際上是按照 Unicode 順序
---
#### 不同型態比較
```javascript=
alert( '2' > 1 );
alert( '01' == 1 );
```
```javascript=
alert( true == 1 );
alert( false == 0 );
```
```javascript=
let a = 0;
alert( Boolean(a) );
let b = "0";
alert( Boolean(b) );
alert(a == b);
```
---
#### 嚴格相等比較
```javascript=
alert( 0 == false );
alert( '' == false );
alert( 0 === false );
```
##### `null` 和 `undefined` 的比較
* 嚴格相等檢查
```javascript=
alert( null === undefined );
```
* 非嚴格相等檢查
```javascript=
alert( null == undefined );
```
---
#### 嚴格相等比較
* 數學運算子 `> < >= <=`
* null -> 0
* undefined -> NaN
* 奇怪的事:`null` vs `0`
```javascript=
alert( null > 0 );
alert( null == 0 );
alert( null >= 0 );
alert( undefined >= 0 );
```
---
#### 嚴格相等比較
* 逃避問題
> `null`、`undefined`
> `===` ~~`> < >= <=`~~
---
#### 小結
* 比較運算子回傳布林值
* 字符串逐字用字母順序進行比較。
* `null` 和 `undefined` 相等(`==`)且不等於其他值
* 使用數學運算子記得分開檢查 `null` 和 `undefined`
---
#### 牛刀小試
```javascript=
5 > 4
"apple" > "pineapple"
"2" > "12"
undefined == null
undefined === null
null == "\n0\n"
null === +"\n0\n"
```
---
### 互動:`alert`、`prompt`、`confirm` (PART 9)
* alert
* prompt
* confirm
* 小結
* 牛刀小試
---
#### alert
```javascript=
alert("Hello");
```
---
#### prompt
```javascript=
let grade = prompt('你大學幾年級?', "一");
alert(`你現在大學${grade}年級!`);
```
* 按 `Esc` 會回傳 `null`
---
#### confirm
```javascript=
let isStudent = confirm("你是學生嗎?");
alert( isStudent );
```
---
#### 小結
* `alert` `prompt` `confirm`
* 出現位置取決於瀏覽器本身
* 外觀也取決於瀏覽器本身
---
#### 牛刀小試
* 簡易的頁面
* 建立一個網站並要求使用者輸入姓名並輸出使用者的姓名。
---
### 條件運算子:`if` 和 `?`
* "if" 陳述式
* 布林轉換
* "else" 區塊
* 更多條件: "else if"
* 條件運算子 ‘?’
* 多個 ‘?’
* ‘?’ 的非使用慣例
---
#### "if" 陳述式
```javascript=
let year = prompt('ECMAScript-2015 標準在哪一年發行?', '');
if (year == 2015) alert( '答對了!' );
```
```javascript=
if (year == 2015) {
alert( "你很棒" );
}
```
> 不要忘記你的大括弧 `{}`
---
#### 布林轉換
> `""`、`null`、`undefined`、`NaN` 會變 `false`
```javascript=
if (0) { // false
...
}
if (1) { // true
...
}
let cond = (year == 2015);
if (cond) {
...
}
```
---
#### "else" 區塊
> 可有可無
```javascript=
let year = prompt('ECMAScript-2015 標準在哪一年發行?', '');
if (year == 2015) {
alert( '猜對了' );
} else {
alert( '為什麼你能猜錯' );
}
```
---
#### 更多條件: "else if"
```javascript=
let year = prompt('ECMAScript-2015 標準在哪一年發行?', '');
if (year < 2015) {
alert( '太早...' );
} else if (year > 2015) {
alert( '太晚' );
} else {
alert( '剛好!' );
}
```
---
#### 條件運算子 ‘?’
```javascript=
let accessAllowed;
let age = prompt('你今年幾歲?', '');
if (age > 18) {
accessAllowed = true;
} else {
accessAllowed = false;
}
alert(accessAllowed);
```
```javascript=
let accessAllowed = (age > 18) ? true : false;
```
---
#### 多個 ‘?’
```javascript=
let age = prompt('age?', 18);
let message = (age < 3) ? 'Hi, baby!' :
(age < 18) ? 'Hello!' :
(age < 100) ? 'Greetings!' :
'What an unusual age!';
alert( message );
```
```javascript=
if (age < 3) {
message = 'Hi, baby!';
} else if (age < 18) {
message = 'Hello!';
} else if (age < 100) {
message = 'Greetings!';
} else {
message = 'What an unusual age!';
}
```
---
#### ‘?’ 的非使用慣例
```javascript=
let company = prompt('哪間公司創造了 JavaScript?', '');
(company == 'Netscape') ?
alert('Right!') : alert('Wrong.');
```
> 雖然可以,但不建議總是用 *問號運算子*
```javascript=
if (company == 'Netscape') {
alert('Right!');
} else {
alert('Wrong.');
}
```
> 可讀性↑
---
#### 牛刀小試
* if ("0")
* ```javascript=
if ("0") {
alert( 'Hello' );
}
```
* 
---
#### 牛刀小試
* 顯示符號
* 用 `if..else` 和 `prompt` 和 `alert` 判斷使用者輸入的數字的正負
* 把 'if' 重寫成 '?'
* ```javascript=
let result;
if (a + b < 4) {
result = 'Below';
} else {
result = 'Over';
}
```
---
#### 牛刀小試
* 把 'if..else' 重寫成 '?'
* ```javascript=
let message;
if (login == 'Employee') {
message = 'Hello';
} else if (login == 'Director') {
message = 'Greetings';
} else if (login == '') {
message = 'No login';
} else {
message = '';
}
```
---
### 邏輯運算子(PART 11)
* `||`(或)
* 或 "||" 找到第一個真值
* `&&` (且)
* 且 "&&" 找到第一個假值
* `!`(非)
---
#### `||`(或)
```javascript=
alert( true || true ); // true
alert( false || true ); // true
alert( true || false ); // true
alert( false || false ); // false
```
```javascript=
let hour = 12;
let isWeekend = true;
if (hour < 10 || hour > 18 || isWeekend) {
alert( 'The office is closed.' );
}
```
---
#### 或 "||" 找到第一個真值
* 從左到右轉成 boolean 判斷
* 遇到第一個 true 回傳,若全 false 則回傳最後一個值
```javascript=
let currentUser = null;
let defaultUser = "John";
let name = currentUser || defaultUser || "unnamed";
alert( name );
```
---
#### `&&` (且)
```javascript=
alert( true && true ); // true
alert( false && true ); // false
alert( true && false ); // false
alert( false && false ); // false
```
```javascript=
let hour = 12;
let minute = 30;
if (hour == 12 && minute == 30) {
alert( 'The time is 12:30' );
}
```
---
#### 且 "&&" 找到第一個假值
* 跟 || 一樣,但真假相反
* 優先權比 || 高
* `a && b || c && d` 等價 `(a && b) || (c && d)`
* 有時也能取代 `if`
```javascript=
let x = 1;
(x > 0) && alert( 'Greater than zero!' );
```
> 但可讀性比較差
---
#### `!`(非)
* 可以把參數轉成布林
* 回傳一個相反的值
```javascript=
alert( !true ); // false
alert( !0 ); // true
```
```javascript=
alert( !!"non-empty string" ); // true
alert( !!null ); // false
```
> Boolean(value) 的簡化版
---
#### 牛刀小試
```javascript=
alert( null || 2 || undefined );
alert( alert(1) || 2 || alert(3) );
alert( 1 && null && 2 );
alert( alert(1) && alert(2) );
alert( null || 2 && 3 || 4 );
```
---
#### 牛刀小試

---
### 迴圈:`while` 和 `for`(PART 12)
* "while" 迴圈
* "do...while" 迴圈
* "for" 迴圈
* 中斷迴圈
* 繼續下一次迭代
* 中斷 / 繼續的標籤
* 小結
* 牛刀小試
---
#### "while" 迴圈
```javascript=
let i = 0;
while (i < 3) { // shows 0, then 1, then 2
alert( i );
i++;
}
let i = 3;
while (i) alert(i--);
```
> 單行 "while" 迴圈可以不用大括弧
---
#### "do...while" 迴圈
```javascript=
let i = 0;
do {
alert( i );
i++;
} while (i < 3);
```
> **最少會執行 1 次**
---
#### "for" 迴圈
```javascript=
for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2
alert(i);
}
```
* 跳過部分
```javascript=
let i = 0;
for (; i < 3;) {
alert( i++ );
}
for (;;) {
// repeats without limits
}
```
---
#### 中斷迴圈
```javascript=
let sum = 0;
while (true) {
let value = +prompt("輸入一個數字", '');
if (!value) break; // (*)
sum += value;
}
alert( '總和: ' + sum );
```
---
#### 繼續下一次迭代
```javascript=
for (let i = 0; i < 10; i++) {
if (i % 2 == 0) continue;
alert(i); // 1, then 3, 5, 7, 9
}
```
> 幫助減少巢狀結構
```javascript=
if (i > 5) {
alert(i);
} else {
continue;
}
(i > 5) ? alert(i) : continue; // continue isn't allowed here
```
> :warning: 無法配合 "?" 使用
---
#### 中斷 / 繼續的標籤
```javascript=
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
let input = prompt(`Value at coords (${i},${j})`, '');
// if an empty string or canceled, then break out of both loops
if (!input) break outer; // (*)
// do something with the value...
}
}
alert('Done!');
```
```javascript=
outer:
for (let i = 0; i < 3; i++) { ... }
```
> :warning: break 和 continue 只能在迴圈內部使用
---
#### 小結
* `while`、`do...while`、`for(;;)`
* 想要直接進行下一次迴圈可以用 `continue`
* `break` / `continue` 支援標籤
---
#### 牛刀小試
```javascript=
let i = 0;
while (++i < 5) alert( i );
let i = 0;
while (i++ < 5) alert( i );
for (let i = 0; i < 5; i++) alert( i );
for (let i = 0; i < 5; ++i) alert( i );
```
* 重複輸入直到輸入正確
* 寫一個迴圈輸出所有小於等於 n 的 "質數"
---
### `"switch"` 陳述式(PART 13)
* 語法
* 範例
* "case" 的群組
* 型態很重要
* 牛刀小試
---
#### 語法
```javascript=
switch(x) {
case 'value1': // if (x === 'value1')
...
[break]
case 'value2': // if (x === 'value2')
...
[break]
default:
...
[break]
}
```
> 由一個或多個 case 和 default(選用) 組成
---
#### 範例
```javascript=
let a = 2 + 2;
switch (a) {
case 3:
alert( 'Too small' );
case 4:
alert( 'Exactly!' );
case 5:
alert( 'Too big' );
default:
alert( "I don't know such values" );
}
```
```javascript=
let a = "1";
let b = 0;
switch (+a) {
case b + 1:
alert("this runs, because +a is 1, exactly equals b+1");
break;
default:
alert("this doesn't run");
}
```
---
#### "case" 的群組
```javascript=
let a = 2 + 2;
switch (a) {
case 4:
alert('Right!');
break;
case 3: // (*) grouped two cases
case 5:
alert('Wrong!');
alert("Why don't you take a math class?");
break;
default:
alert('The result is strange. Really.');
}
```
---
#### 型態很重要
```javascript=
let arg = prompt("Enter a value?");
switch (arg) {
case '0':
case '1':
alert( 'One or zero' );
break;
case '2':
alert( 'Two' );
break;
case 3:
alert( 'Never executes!' );
break;
default:
alert( 'An unknown value' );
}
```
---
#### 牛刀小試
* 將 "switch" 改寫成 "if"
* ```javascript=
switch (browser) {
case 'Edge':
alert( "You've got the Edge!" );
break;
case 'Chrome':
case 'Firefox':
case 'Safari':
case 'Opera':
alert( 'Okay we support these browsers too' );
break;
default:
alert( 'We hope that this page looks ok!' );
}
```
---
#### 牛刀小試
* 將 "if" 改寫成 "switch"
* ```javascript=
let a = +prompt('a?', '');
if (a == 0) {
alert( 0 );
}
if (a == 1) {
alert( 1 );
}
if (a == 2 || a == 3) {
alert( '2,3' );
}
```
---
### 函式
* 函式宣告
* 區域變數
* 外部變數
* 參數
* 預設值
* 回傳值
* 函式命名
* 函式 == 註解
* 小結
* 牛刀小試
---
#### 函式宣告
```javascript=
function showMessage() {
alert( 'Hello everyone!' );
}
showMessage();
showMessage();
```
---
#### 區域變數
```javascript=
function showMessage() {
let message = "Hello, I'm JavaScript!"; // local variable
alert( message );
}
showMessage(); // Hello, I'm JavaScript!
alert( message ); // <-- Error! The variable is local to the function
```
---
#### 外部變數
```javascript=
let userName = 'John';
function showMessage() {
let message = 'Hello, ' + userName;
alert(message);
}
showMessage(); // Hello, John
```
> 全域變數
---
#### 參數
```javascript=
function showMessage(from, text) {
from = '*' + from + '*'; // make "from" look nicer
alert( from + ': ' + text );
}
let from = "Ann";
showMessage(from, "Hello"); // *Ann*: Hello
// the value of "from" is the same, the function modified a local copy
alert( from ); // Ann
```
---
#### 預設值
```javascript=
showMessage("Ann");
```
> Undefiened
```javascript=
function showMessage(from, text = "no text given") {
alert( from + ": " + text );
}
showMessage("Ann"); // Ann: no text given
```
> 舊的方式 `if (text === undefiend)` 或 `||`
---
#### 回傳值
```javascript=
function checkAge(age) {
if (age > 18) {
return true;
} else {
return confirm('Do you have permission from your parents?');
}
}
let age = prompt('How old are you?', 18);
if ( checkAge(age) ) {
alert( 'Access granted' );
} else {
alert( 'Access denied' );
}
```
> 沒寫 return 或沒 return 值 (?
---
#### 函式命名
```javascript=
showMessage(..) // shows a message
getAge(..) // returns the age (gets it somehow)
calcSum(..) // calculates a sum and returns the result
createForm(..) // creates a form (and usually returns it)
checkPermission(..) // checks a permission, returns true/false
```
* 一個函式,一個動作
* 極短函數名稱,`$` jQuery、`_` Loadsh
---
#### 函式 == 註解
```javascript=
function showPrimes(n) {
nextPrime: for (let i = 2; i < n; i++) {
for (let j = 2; j < i; j++) {
if (i % j == 0) continue nextPrime;
}
alert( i ); // a prime
}
}
```
```javascript=
function showPrimes(n) {
for (let i = 2; i < n; i++) {
if (!isPrime(i)) continue;
alert(i); // a prime
}
}
function isPrime(n) {
for (let i = 2; i < n; i++) {
if ( n % i == 0) return false;
}
return true;
}
```
---
#### 小結
```javascript=
function name(parameters, delimited, by, comma) {
/* code */
}
```
* 作為參數傳給函式的值會複製一份並成為函數內的區域變數
* 函式可以存取外部變數。
* 函式可以回傳一個值,若無則回傳 `undefined`
#### 小結
函式命名
* 名稱應清楚地描述該功能的作用。
* 函式是一個動作,因此函數名稱通常是口頭的。
* 存在許多著名的前綴 `create` `get` `show` `set` 用來提示函式的功能。
---
#### 牛刀小試
* 寫函式 `min` 可以回傳參數中的最小值
```javascript=
min(2, 5) == 2
min(3, -1) == -1
min(1, 1) == 1
```
---
### 函式表達式和箭頭
> 在 JavaScript 中,函式不是神奇的語言結構,而是一種特殊的值
* 回調函式
* 函式表達式 vs 函式宣告
* 箭頭函式
* 小結
* 牛刀小試
---
#### 回調函式(Callback functions)
```javascript=
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
function showOk() {
alert( "You agreed." );
}
function showCancel() {
alert( "You canceled the execution." );
}
// usage: functions showOk, showCancel are passed as arguments to ask
ask("Do you agree?", showOk, showCancel);
```
> `showOk` 和 `showCancel` 在這就是回調函式
---
#### 函式表達式(Function Expression) vs 函式宣告(Function Declaration)
```javascript=
sayHi("John"); // Hello, John
function sayHi(name) {
alert( `Hello, ${name}` );
}
```
```javascript=
sayHi("John"); // error!
let sayHi = function(name) { // (*) no magic any more
alert( `Hello, ${name}` );
};
```
---
#### 箭頭函式(Arrow functions)
```javascript=
let func = (arg1, arg2, ...argN) => expression
let age = prompt("What is your age?", 18);
let welcome = (age < 18) ?
() => alert('Hello') :
() => alert("Greetings!");
welcome();
```
> 箭頭函式還有其他有趣的功能,在之後會有一個章節再詳細介紹。
---
#### 小結
* 函式就是值。可以在程式的任何位置指派,複製或宣告它們。
* 函式宣告在相同作用域下,都可以調用。
* 函式表達在執行之後才可以使用。
* 箭頭函式的 expresssion 部分若加大括弧則需 return 才能回傳值
---
#### 牛刀小試
* 用箭頭函式改寫
```javascript=
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
ask(
"Do you agree?",
function() { alert("You agreed."); },
function() { alert("You canceled the execution."); }
);
```
---
### JavaScript 的特別回顧
* 程式架構
* 嚴格模式
* 變數
* 互動
* 運算子
* 迴圈
* "switch" 結構
* 函式
* 還有更多
---
#### 程式架構
```javascript=
alert('Hello'); alert('World');
alert('Hello')
alert('World')
alert("There will be an error after this message")
[1, 2].forEach(alert)
function f() {
// no semicolon needed after function declaration
}
```
---
#### 嚴格模式
```javascript=
'use strict';
...
```
---
#### 變數
* 用 `let` `var` `const` 宣告
* 7 種資料型態 `number` `string` `boolean` `null` `undefined` `object` `symbol`
```javascript=
typeof null == "object" // error in the language
typeof function(){} == "function" // functions are treated specially
```
---
#### 互動
```javascript=
let userName = prompt("Your name?", "Alice");
let isTeaWanted = confirm("Do you want some tea?");
alert( "Visitor: " + userName ); // Alice
alert( "Tea wanted: " + isTeaWanted ); // true
```
---
#### 運算子
* 算術
* 指派
* 位元
* 條件
* 邏輯
* 比較
* 其他...
---
#### 迴圈
```javascript=
// 1
while (condition) {
...
}
// 2
do {
...
} while (condition);
// 3
for(let i = 0; i < 10; i++) {
...
}
```
> break/continue 來打破循環
---
#### "switch" 結構
```javascript=
let age = prompt('Your age?', 18);
switch (age) {
case 18:
alert("Won't work"); // the result of prompt is a string, not a number
case "18":
alert("This works!");
break;
default:
alert("Any value not equal to one above");
}
```
---
#### 函式
```javascript=
function sum(a, b) {
return a + b;
}
let sum = function(a, b) {
return a + b;
};
let sum = (a, b) => a + b;
```
---
#### 還有更多
> 到目前為止,講的是 JavaScript 的基礎用法與知識,之後還有更多特殊的用法和進階的功能。
---
## 最後
參考來源:<https://javascript.info>、MDN
{{ slido 回應 }}
{{ 這邊要放 QRCODE ㄅ }}
{{ 下次社課ㄅ }}
{"metaMigratedAt":"2023-06-15T00:07:52.096Z","metaMigratedFrom":"YAML","title":"喵喵用瀏覽器學現代 JavaScript - 基礎","breaks":true,"description":"第 2 堂","contributors":"[{\"id\":\"b107bcc6-fc73-449e-a017-dde08de3353c\",\"add\":27783,\"del\":2841}]"}