# 基礎 連結:<https://hackmd.io/@ntust/ncc-js-2> ![QRCode](https://imgur.com/zvOv4hT.png) --- ## 講者 - 四資管四 徐孟辰 --- ## 本次社課 * 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'; ``` --- #### 真實的比喻 ![](https://i.imgur.com/N97FEkH.png) ![](https://i.imgur.com/aGT0sUc.png) ```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> ![圖 ref: javascript.info](https://i.imgur.com/wH9U2WB.png) --- #### 指派(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' ); } ``` * ![](https://i.imgur.com/7Imm4nc.png) --- #### 牛刀小試 * 顯示符號 * 用 `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 ); ``` --- #### 牛刀小試 ![](https://i.imgur.com/y06ObTN.png) --- ### 迴圈:`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}]"}
    305 views
   Owned this note