<style>
.slides img{background-color:grey!important}
.slides img[title^='"']{filter:invert(100%)}
hr, .slides [title^='*']{display:none}
summary h1{display:inline;border-bottom:0!important}
</style>
<!-- .slide: data-background="black" -->
###### [JavaScript 教學/](/@NCHUIT/js)
:::spoiler {state=open}<h1>回顧複習</h1>
+ <i class="fa fa-book"></i> 網頁 md.nchuit.cc/js
+ <i class="fa fa-tv"></i> 簡報 md.nchuit.cc/js5
[ToC]
:::
> [name=VJ]
----
## `*.html` 基礎框架
```htmlmixed
<html>
<head>
<title>網頁標題</title>
<meta name="description" content="網頁描述">
<link rel="icon" href="https://hackmd.io/favicon.png">
<!--以及更多-->
</head>
<body>
網頁內容
</body>
</html>
```
你可能注意到了...
`<head>`內的元素都不需要用`</*>`關起來
###### [HTML稍微詳細的介紹: 從HTML到MarkDown(建議閱讀)](/@NCHUIT/mdhtml)
----
### JavaScript 又在哪呢?
HTML 的 [`<script>`元素](https://developer.mozilla.org/zh-TW/docs/Web/HTML/Element/script)
```htmlmixed
<script>
// JavaScript 寫在這裡
</script>
```
:::info
🕹快捷鍵: 在 <i class="fa fa-fw fa-chrome"></i>Chrome 或 <i class="fa fa-fw fa-internet-explorer"></i>Edge 瀏覽器中按下 <kbd>F12</kbd> 或 <kbd>Ctrl + Shift + I</kbd> 可以在 `Elements` 頁面檢視所有 HTML 元素。
:::
----

▲ <kbd>Ctrl</kbd>+<kbd>F</kbd> 搜索 `<script>`
----
#### <i class="fa fa-fw fa-gamepad"></i>動動手: 主控台~~入侵~~
試對瀏覽器開發者工具的主控台發送以下指令:
```javascript
document.body.innerHTML="Hello"
```
:::info
🕹快捷鍵: 在 <i class="fa fa-fw fa-chrome"></i>Chrome 或 <i class="fa fa-fw fa-internet-explorer"></i>Edge 瀏覽器中按下 <kbd>F12</kbd> 或 <kbd>Ctrl+Shift+I</kbd> 可以打開瀏覽器的開發者工具,請在 `console`(`主控台`) 頁面輸入並發送指令。
:::
```javascript
onbeforeunload=()=>true
```
---
### <i class="fa fa-fw fa-gamepad"></i>動動手: 存檔


----
#### `檔名.html`
```htmlmixed
<script>
alert('Hello world')
// ...或更多程式碼~
</script>
```
----


----
#### `純程式碼.js`
```javascript
alert('哈囉')
// ...或更多程式碼~
```
要搭配下面 `啟動器.html` 來打開 <span><!-- .element: class="fragment" data-fragment-index="1" -->[utf-8?](https://zh.wikipedia.org/wiki/%E4%B8%AD%E6%96%87%E4%BA%82%E7%A2%BC)</span>
```htmlembedded
<script charset='utf-8' src='純程式碼.js'></script>
```
或是下載 [Node.js](https://nodejs.org/zh-tw/download/current),親測要裝蠻久的先放著吧
---
## 宣告 Declare
```javascript=
var 變數V;
var 變數VV = '我有初始值';
let 變數L = '我只能在目前作用域使用'
變數 = '我是直接宣告的~'
```
連續宣告
```javascript=
var a = "A", b = a;
// 等同於
var a, b = a = "A";
```
----
### 作用域
```javascript=
{
let 變數let = 'NCHUIT'
}
// 在這 *不可以* 存取變數let
```
```javascript=
{
var 變數var = 'NCHUIT'
}
// 在這 *可以* 存取變數var
```
```javascript=
// 在這 *不可以* 存取變數flet
function 函式() {
let 變數flet = 'NCHUIT'
// 在這 *可以* 存取變數flet
}
// 在這 *不可以* 存取變數flet
```
----
### 簡易輸出入
簡易輸出
```javascript=
alert('視窗輸出')
console.log('主控台輸出')
```
簡易輸入語法
```javascript=
變數 = prompt('輸入提示')
```
----
:::spoiler 練習: 試變動下面程式碼使之正常顯示變數
參考答案
```javascript=
{
let 變數 = 'NCHUIT'
window.變數 = 變數
}
alert(變數)
```
:::
```javascript=
{// 提示: 這裡是區塊內
let 變數 = 'NCHUIT'
// 在這行加個宣告
}// 提示: 這裡是window
alert(變數)
```
提示: 任何區塊用 `window.x=123` 等同於無區塊用 `x=123`
---
## 字串 `string`
語法、拼接字串
```javascript=
var a = '國立中興大學'
var b = '資訊科學研習社'
var x = a + b
alert(x) // 彈出: 國立中興大學資訊科學研習社
```
----
[格式化字串](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Text_formatting)
```javascript= [|1,2,3,4]
alert('我就是要印出 " ') // 也可以直接使用
alert('我就是要印出 \' ')
alert("我就是要印出 ' ")
alert("我就是要印出 \" ")
alert("第一行\n第二行") // 換行用 \n
alert(`第一行
第二行`) // 重音符可以讓你在字串中換行
```
[格式化輸出](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Template_literals)
```javascript= [|1,2,3,4]
var 身高cm = 165, 體重kg = 45, 溫度C = 30
alert(`身高: ${身高cm/2.54}英吋
體重: ${體重kg}
BMI: ${體重kg/(身高cm*.01)**2}
${溫度C}℃=${(溫度C*9/5)+32}℉`)
```
----
## [數值 Number](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Number), [布林值 Boolean](https://www.w3schools.com/js/js_booleans.asp)
```javascript
var x = 10, // 一般整數
y = 3.14, // 小數
z = 0xa, // 16進制
i = 010, // 8進制
j = 0b101; // 2進制
var a = true, b = false;
```
---
## [運算](https://www.w3schools.com/js/js_operators.asp)
|運算子|名稱|範例|答
|-:|-|-|-
|`+` |加法|`8 + 9`|`17`<!-- .element: class="fragment" data-fragment-index="1" -->
|`-` |減法|`7 - 1`|`6`<!-- .element: class="fragment" data-fragment-index="2" -->
|`*` |乘法|`3 * 7`|`21`<!-- .element: class="fragment" data-fragment-index="3" -->
|`/` |除法|`2 / 3`|`0.66...`<!-- .element: class="fragment" data-fragment-index="4" -->
|`**`|乘方|`2 ** 11`|`2048`<!-- .element: class="fragment" data-fragment-index="5" -->
----
|運算子|名稱|範例|答
|-:|-|-|-
|`&&`|且|`x < 10 && y > 1`|`true`<!-- .element: class="fragment" data-fragment-index="1" -->
|`\|\|`|或|`x == 5 \|\| y == 5`|`false`<!-- .element: class="fragment" data-fragment-index="2" -->
|`!`|非|`!(x == y)`|`true`<!-- .element: class="fragment" data-fragment-index="3" -->
----
### 比較運算
|運算子|名稱|範例(`x=5`)|答
|-:|-|-|-
|`<`|小於|`age < 30`|`false`?<!-- .element: class="fragment" data-fragment-index="1" -->
|`>`|大於|`girl_friend > 1`|`false`<!-- .element: class="fragment" data-fragment-index="2" -->
|`>=`|不小於|`x >= 8`|`false`<!-- .element: class="fragment" data-fragment-index="3" -->
|`<=`|不大於|`x <= 8`|`true`<!-- .element: class="fragment" data-fragment-index="4" -->
----
|運算子|描述|範例(`x=5`)|答
|-:|-|-|-
|`==`|等於|`x == 8`<br>`x == 5`<br>`x == "5"` |<span>`false`<!-- .element: class="fragment" data-fragment-index="1" --></span><br><span>`true`<!-- .element: class="fragment" data-fragment-index="2" --></span><br><span>`true`<!-- .element: class="fragment" data-fragment-index="3" --></span>
|`!=`|不等於|`x != 8`|`true`<!-- .element: class="fragment" data-fragment-index="4" -->
|`===`|[型態](/h1l_j7hySAuLQIMCo36K7Q?view)、值都相等|`x === 5`<br>`x === "5"`|<span>`true`<!-- .element: class="fragment" data-fragment-index="5" --></span><br><span>`false`<!-- .element: class="fragment" data-fragment-index="6" --></span>
|`!==`|型態、值不相等|`x !== 5`<br>`x !== "5"`<br>`x !== 8`|<span>`false`<!-- .element: class="fragment" data-fragment-index="7" --></span><br><span>`true`<!-- .element: class="fragment" data-fragment-index="8" --></span><br><span>`true`<!-- .element: class="fragment" data-fragment-index="9" --></span>
---
### 賦值運算
如果你只是簡單想將兩個字串加在一起,你可以這樣做:
```javascript
name += ' says hello!'
```
<p>相當於</p>
```javascript
name = name + ' says hello!'
```
----
通常流程處理才用得上
|賦值運算|範例|等義於
|-|-|-
|`=`|`x = y`|`x = y`
|`+=`|`x += y`|`x = x + y`
|`++`|`x++`; `++x`|`x += 1`
|`-=`|`x -= y`|`x = x - y`
|`--`|`x--`; `--x`|`x -= 1`
----
|賦值運算|範例|等義於
|-|-|-
|`*=`|`x *= y`|`x = x * y`
|`**=`|`x **= y`|`x = x ** y`
|`/=`|`x /= y`|`x = x / y`
|`%=`|`x %= y`|`x = x % y`
----
2進制處理賦值運算
|賦值運算|範例|等義於
|-|-|-
|`<<=`|`x <<= y`|`x = x << y`
|`>>=`|`x >>= y`|`x = x >> y`
|`>>>=`|`x >>>= y`|`x = x >>> y`
|`^=`|`x ^= y`|`x = x ^ y`
|`&=`|`x &= y`|`x = x & y`
|`\|=`|`x \|= y`|`x = x \| y`
----
:::spoiler 練習: 不執行,說出下面每行`alert`出現的數字
1. 1,2
2. 3,3
3. 4,4
4. 4,3
5. 4,4
6. 5,5
7. 14
8. 64
+
9. 3
10. 4
11. 22 (0b10110)
12. 6 (0b110)
13. $2^{31}-1$
14. 11 (0b1011)
15. 0
16. 30 (0b11110)
:::
```javascript=
x=1; alert(x++); alert(x)
x=2; alert(++x); alert(x)
x=3; alert(x+=1); alert(x)
x=4; alert(x--); alert(x)
x=5; alert(--x); alert(x)
x=6; alert(x-=1); alert(x)
x=7; alert(x*=2); alert(x)
x=8; alert(x**=2); alert(x)
x=9; alert(x/=3); alert(x)
x=10; alert(x%=6); alert(x)
x=0b1011; alert(x<<=1); alert(x) //11=0b1011
x=0b1100; alert(x>>=1); alert(x) //12=0b1100
x=-1; alert(x>>>=1); alert(x) //-1=0b1...1(32個1)
x=0b1110; alert(x^=0b0101); alert(x) //14=0b1110
x=0b1111; alert(x&=0); alert(x) //15=0b1111
x=0b10000;alert(x|=0b01110);alert(x) //16=0b10000
```
---
## [函式 `function`](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Functions)
###### 也是物件
```javascript=
函式 = function(){
console.log("訊息")
}
```
### 另一種寫法
```javascript=
function 函式(){
console.log("訊息")
}
```
----
### 用處?
用於**呼叫**,簡化程式
```javascript=
函式 = function(){
console.log("睡覺")
console.log("念書")
console.log("玩遊戲")
}
函式()
函式()
```
---
## 陣列 Array
```javascript
陣列 = [123, 'word', true, 3.14]
```
| 索引 | 陣列的東西 |
| ---- | -------- |
| 0 | `123` |
| 1 | `'word'` |
| 2 | `true` |
| 3 | `3.14` |
取用陣列某一個東西:`陣列[0]`、`陣列[1]`
例如這邊 `陣列[3]` 就會取到 `3.14`
----
## 物件 Object
```javascript=
var 某人 = {
暱稱 : 'VJ',
年齡 : 22,
性別 : '男',
興趣 : ['看韓劇', '睡覺', '電腦遊戲'],
高中畢業與否 : true,
打招呼 : function() {
alert('Hello world')
}
};// 體驗社課的例子
```
----
|屬性|物件的東西
|-:|-
|`暱稱`|`'VJ'`
|`年齡`|`22`
|`性別`|`'男'`
|`興趣`|陣列
|`高中畢業與否`|`true`
|`打招呼`|函式
----
:::spoiler 練習: `BMI.html`
```htmlembedded=
<script>
身高 = prompt('請輸入身高(cm)')
體重 = prompt('請輸入體重(kg)')
alert(`身高: ${身高}
體重: ${體重}
BMI: ${體重/(身高*.01)**2}`)
</script>
```
:::
試用輸出入寫一個 BMI 計算器 [...wiki](https://zh.wikipedia.org/wiki/%E8%BA%AB%E9%AB%98%E9%AB%94%E9%87%8D%E6%8C%87%E6%95%B8)
正常範圍是 $18.5$ ~ $25$,公式
$$
BMI = 體重(kg) / 身高^2(m^2)
$$
例如一個$52kg$的人,身高是$155cm$,則
$$
52/1.55^2 = 21.6(kg/m^2)
$$
提示: 還記得[存檔](#動動手-存檔)和[運算子](#運算子)嗎?
----
:::spoiler 練習: 讓`壞人.會做的事()`可以直接呼叫
```javascript= [|9|18,19,23,24,26]
class 人{
constructor(暱稱,年齡,性別,興趣,高中畢業與否){
this.暱稱=暱稱
this.年齡=年齡
this.性別=性別
this.興趣=興趣
this.高中畢業與否=高中畢業與否
}
static 打招呼() {
alert('Hello world')
}
}
class 壞人 extends 人{
constructor(暱稱,年齡,性別,興趣,高中畢業與否,壞事) {
super(暱稱,年齡,性別,興趣,高中畢業與否)
this.壞事=壞事
}
static 你的回應
static 打招呼() {
super.打招呼()
this.你的回應 = prompt('do three small')
}
static 挑事() {
alert(this.你的回應+"?! 你是想找碴嗎?")
}
static 會做的事(){
this.打招呼()
this.挑事()
}
}
壞人.會做的事()
```
:::
```javascript= [|1,13]
class 人{
constructor(暱稱,年齡,性別,興趣,高中畢業與否){
this.暱稱=暱稱
this.年齡=年齡
this.性別=性別
this.興趣=興趣
this.高中畢業與否=高中畢業與否
}
打招呼() {
alert('Hello world')
}
}
class 壞人 extends 人{
constructor(暱稱,年齡,性別,興趣,高中畢業與否,壞事) {
super(暱稱,年齡,性別,興趣,高中畢業與否)
this.壞事=壞事
}
打招呼() {
super.打招呼()
this.你的回應 = prompt('do three small')
}
挑事() {
alert(你的回應+"?! 你是想找碴嗎?")
}
會做的事(){
this.打招呼()
this.挑事()
}
}
壞人.會做的事() // error
```
提示: `static`
----
### new (v.)
**保留字**,用 **類別名稱**(**Class Name**) 取代建構子以**描繪/建構**(**construct**) 物件,語法同 Java
```javascript=
某人1 = new 人('VJ', 22, '男', ['看韓劇', '電腦遊戲'], true)
某人2 = new 人('??', 13, '女', ['念書', '化妝'], false)
某人3 = new 人('!!', 42, '男', ['綜藝', '政治'], false)
某人4 = new 人('@@', 20, '女', ['貓咪', '狗勾'], true)
```
就...重複使用會比較短/便捷,同函式
做做接下來的練習你就知道為啥需要ㄓㄟˋ個
----
:::spoiler 練習: 試直接寫出上面`new`出來的物件,提示:
```javascript=
某人1 = {
暱稱: 'VJ',
年齡: 22,
性別: '男',
興趣: ['看韓劇', '電腦遊戲'],
高中畢業與否: true,
打招呼: function() {
alert('Hello world')
}
}
某人2 = {
暱稱: '??',
年齡: 13,
性別: '女',
興趣: ['念書', '化妝'],
高中畢業與否: false,
打招呼: function() {
alert('Hello world')
}
}
某人3 = {
暱稱: '!!',
年齡: 42,
性別: '男',
興趣: ['綜藝', '政治'],
高中畢業與否: false,
打招呼: function() {
alert('Hello world')
}
}
某人4 = {
暱稱: '@@',
年齡: 20,
性別: '女',
興趣: ['貓咪', '狗勾'],
高中畢業與否: true,
打招呼: function() {
alert('Hello world')
}
}
```
:::
```javascript=
物件1 = {
屬性1: 屬性1值,
屬性2: 屬性2值,
...
方法1(){ ... }
}
物件2 = { ... }
```
---
## 判斷句 [if...else](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/if...else)
```javascript=
if (條件1)
執行1
else if (條件2)
執行2
else if (條件3)
執行3
...
else
執行N
```
----
::: spoiler 練習: [閏年](https://zh.wikipedia.org/wiki/闰年)判斷
解
```javascript=
y = prompt('輸入年份讓程式判斷是否為閏年')
if(y%4!=0) alert('平年')
else if(y%4==0 && y%100!=0) alert('閏年')
else if(y%100==0 && y%400!=0) alert('平年')
else if(y%400==0) alert('閏年')
else alert('平年')
```
縮短
```javascript=
y = prompt('輸入年份讓程式判斷是否為閏年')
if(y%4==0 && y%100!=0 || y%400==0) alert('閏年')
else alert('平年')
```
:::
輸入年份讓程式判斷是否為閏年
閏年定義
: 非4的倍數,為平年。
4的倍數但非100的倍數,為閏年。
100的倍數但非400的倍數,為平年。
400的倍數為閏年。
範例
```
輸入: 1600
輸出: 閏年
```
```
輸入: 1000
輸出: 平年
```
----
## 迴圈 `while`, `for`
Before (`while`)
```javascript= [|2,3,5]
陣列 = [123, 'word', true, 3.14]
索引 = 0
while(索引 < 4){
alert(`第${索引}個: ${陣列[索引]}`)
索引++
}
```
After (`for`)
```javascript= [|2]
陣列 = [123, 'word', true, 3.14]
for(索引 = 0; 索引 < 4; 索引++){
alert(`第${索引}個: ${陣列[索引]}`)
}
```
`索引++` 等同於 `索引=索引+1` 或 `索引+=1`
----
:::spoiler 練習: 印星星
```javascript=
n = prompt('輸入數字n,將印出 n*n 的星星方陣')
結果 = ''
for (i = 0; i++ < n;){
for (j = 0; j++ < n;)
結果+='*'
結果+='\n'
}
alert(結果)
```
:::
輸入一個數字`n`
印出 `n*n` 的星星方陣
例
```
輸入:3
輸出:
***
***
***
```
提示
1. 你會需要用到一個變數紀錄結果
2. 用 `變數+='*'` 在同一行多印一顆 `*`
3. 用 `變數+='\n'` 換行
---
## 函式 function
Why Functions?
<!-- You can reuse code: Define the code once, and use it many times. -->
<!-- You can use the same code many times with different arguments, to produce different results. -->
1. 重複使用程式碼: 定義一次,跑千萬次
2. 回傳不同結果: 傳入不同參數,產生不同回傳值
3. 寫給人家 (例: LINE Notify, gapi)
```javascript=
function BMI(身高cm,體重kg){
return 體重kg/(身高cm*.01)**2
}
alert(BMI(165,45))
alert(BMI(159,44))
```
----
一般寫法
```javascript=
function 函式名稱(參數1, 參數2, 參數3) {
// 程式碼
}
```
物件定義寫法
```javascript=
函式名稱 = function(參數1, 參數2, 參數3) {
// 程式碼
}
```
----
::: spoiler 練習: 除錯
```javascript=
function f(名, 姓){
alert(姓+名)
}
f('維傑','談')
```
:::
執行下面程式碼會怪怪的,請修改第4行讓它正常運行。
```javascript=
function f(名, 姓){
alert(姓+名)
}
f('維傑') // 改這行
```
----
::: spoiler 練習: 檢驗質數
```javascript=
function 檢驗質數(n){
if(n==2) return true
const s = n**0.5+1
for(i = 2; i < s; i++)
if(n%i==0) return false
return true
}
alert(檢驗質數(1117))
```
:::
寫一個含一個引數的函式(如下),判斷`n`是不是質數(回傳`true`或`false`)。
```javascript=
function 檢驗質數(n){
// TO-DO
}
alert(檢驗質數(1117))
```
---
### [參數 Parameters](https://developer.mozilla.org/zh-TW/docs/Glossary/Parameter)
寫函式的時候我們稱括號`()`裡的變數為**參數**
```javascript=
function 檢驗質數(n){ // n 就是 參數
if(n==2) return true
const s = n**0.5+1
for(i = 2; i < s; i++)
if(n%i==0) return false
return true
}
```
----
### [引數 Arguments](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Functions/arguments)
呼叫函式時,我們稱傳入的資料為**引數**
```javascript=
function f(參數1, 參數2, 參數3) {
alert(參數1)
alert(arguments[0])
}
f('hello','world','!')
// 'hello','world','!' 都是 引數
```
----
## [解構賦值](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
```javascript=
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(rest);
// expected output: Array [30,40,50]
```
:::spoiler 練習: 交換兩數
```javascript=
var a=1,b=2;
[a,b]=[b,a]
alert(`a=${a},b=${b}`)
```
:::
```javascript=
var a=1,b=2;
// TO-DO
alert(`a=${a},b=${b}`)
```
---
## [HTML 事件處理器屬性](https://developer.mozilla.org/zh-TW/docs/Web/HTML/Global_attributes)
`onclick`, `onbeforeunload`
:::spoiler 練習: `按鈕.html`
```htmlembedded=
<button onclick="alert('Hello world!')">
按鈕1
</button>
<button id="按鈕">
按鈕2
</button>
<script>
按鈕 = document.getElementById("按鈕")
按鈕.addEventListener("click", e => {
alert('Hello world!')
});
</script>
```
:::
用HTML寫出一個按鈕([`<button>`](https://www.w3schools.com/tags/tag_button.asp)),使得按下它時出現Hello world
提示1
```htmlembedded=
<button onclick="/*你的JavaScript程式碼*/">
按鈕顯示名稱
</button>
```
----
提示2
```htmlembedded=
<button id="按鈕">
按鈕顯示名稱
</button>
<script>
按鈕 = document.getElementById("按鈕")
按鈕.addEventListener("click", e => {
/*你的JavaScript程式碼*/
});
</script>
```
----
## 補充: 傳入物件
```javascript=
var 無鋒劍 = {等級: 1, 基礎攻擊: 32}
var 你的原神角色 = {
名字 : '芙寧娜',
武器 : 無鋒劍,
性別 : '女',
元素附著 : '水',
命座 : -1, 等級 : 0, 經驗: 0,
元素爆發需求 : 60,
元素能量 : 0,
元素戰技 : function 孤心沙龍(){},
元素爆發 : function 萬眾狂歡(){
if(元素能量 >= 元素爆發需求)
alert(`欸嘿`);
else alert(`元素能量不足`);
},
}
function f(物件){
要印出的 = 物件.性別
alert(要印出的);
}
f(你的原神角色)
```
{"metaMigratedAt":"2023-06-16T21:25:35.520Z","metaMigratedFrom":"YAML","breaks":true,"description":"JavaScript教學-110-2主題社課-國立中興大學資訊科學研習社","title":"回顧複習","contributors":"[{\"id\":\"6d6e3ba2-6820-4c6f-9117-f09bccc7f7aa\",\"add\":311,\"del\":182},{\"id\":\"e86b6571-4dea-4aa4-ba20-ece559b0e015\",\"add\":18275,\"del\":2271}]"}