---
# System prepended metadata

title: JavaScript

---

# JavaScript

[TOC]

HEEEEELLLO

## JavaScript 簡介

-   JavaScript 和 JAVA 之間的關係?
-   寫一些簡介.....

## 基礎語法

### 撰寫一個 HelloWorld

-   JS 語法是從上到下，依序執行。
```htmlembedded
<script text="text/javascript">
        // 控制器彈出一個警告框
        alert("這是一個警告彈窗。");
        // 向控制台輸出一個內容
        console.log("這是一串在控制台輸出的文字。")
        // 讓計算機在頁面輸出一個內容
        document.write("這是一串在頁面中輸出的文字。")
</script>
```

![](https://hackmd.io/_uploads/ryHR_IoI2.png)

### JS 的編寫位置

JS的代碼編寫主要有四種方式

**第一種:** 寫在onclick屬性之中 ［不推薦］
```htmlmixed
<button onclick="alert('按鈕被點擊了!')">點我一下</button>
```

**第二種:** 寫在href屬性之中 ［不推薦］
```htmlmixed
<a href="javascript:alert('按鈕被點擊了!')">點我一下</a>
```

第一、二種方式，不方便維護

**第三種:** 引用 外部 JS 文件　［推薦使用方式］
在 HTML 語法中，插入外部 JS文件

```htmlmixed
<script text="text/javascript" src="/path/script.js"></script>
```

**第四種:** 在內部script1標籤內撰寫JS代碼
```htmlembedded
<script text="text/javascript">
        // JS 代碼撰寫的地方
</script>
```


### JS 註釋

要養好一個註釋的習慣，也可以通過註釋來協助編寫代碼。
(把一些代碼註釋掉，觀察結果)

**多行註釋:** 
```javascript
/*
 * 多行註釋
 * /
```

**單行註釋:** 
```javascript
// 單行註釋
```


### JS 代碼的一些規定
1. 嚴格區分大小寫
    Alert("Hello World"); [錯誤]
    alert("Hello World"); [正確]
2. 每一條指令以 ";" 分號作為結尾。當然也可以不填寫，瀏覽器會自動添加，但是這樣會造成系統資源浪費。
3. JS會自動忽略換行跟空格，所以可以利用空格跟換行讓代碼更整潔。


### 字面量與變量
1. 字面量是不可改變的值。例如: 1,2,3,4, "String"，但我們一般不使用字面量，因為沒有任何意義。
2. 變量可以用來保存字面量，變量中的值，可以被任意改變。 例如: X = 5; X = 25;
3. 在js中用 var 來聲明變量。 var x; console.log(x); 
    (如果沒有聲明，直接使用未宣告變量，會導致error)
4. 聲明和賦值可以同時執行。 var x = 153;
5. 變量的命名盡量要有意義。例如 age = 12 等等

### 變量的命名規則
1. 標示符可以含有字母、數字、_、$。
2. 標示符不可以用數字開頭。
3. 標示符不能是 JS 中的關鍵字或保留字。 例如: var、if、else、console...。
4. 標示符一般採用駝峰命名法(首字母小寫，每個單詞開頭大寫，其餘小寫)。例如: helloWorld。
5. 底層保存標示符號採用 Unicode 編碼 (utf-8)。但盡量不要用英文以外的來命名。

### 六種數據類型

1. 數據類型指的是字面量的類型。
2. JS中一共有六種數據類型
3. String 字串，使用單雙引號包住。例子: "這是一個字符串"，單雙引號可以混著用。(其餘規則跟字串使用一樣)
4. Number 數值。
5. Boolean 布爾值。只有兩個[真]true [假]false，用於邏輯判斷使用。
6. Null 專門表示空的對象，typeof會返回object。
7. Undefined 未定義。聲明一個變量不給值，會是Undefined。
8. Object 物件
9. 其中 Object 是引用數據類型，其餘為基本數據類型。
10. 檢查類型指令: typeof 變數名稱
11. JS 中的最大值: Number.MAX_VALUE。
12. Infinity: 無窮值。
13. NaN: Not a number 是一種特殊數字。
14. JS中的數值運算不是一個精確值，會得到部精確的結果。(JS不好解決)

<!-- 閱讀範圍: 尚硅谷 教學 2-10 -->

### JS 語句 statement

==重點筆記==
* 程序是由一條一條的語句所構成。
* 程式中的的語句默認是由上而下，依序執行
* JS 中使用 {} 來對語句進行分組。
* 同一個 {} 被稱為一組語句，或一個代碼塊。
* JS中的代碼塊只有 **分組** 的作用，沒有其他用途。
```javascript
{
    alert("....");
    console.log("...")
} # 代碼塊

```
**參考視頻** [27 尚硅谷 JS基础 代码块](https://www.youtube.com/watch?v=vted64Bv5Qs&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=27)

---------------------------

## 流程控制語句

* JS的程序是由上而下依序執行
* 通過流程控制可以控制程序執行的流程
* 使程序可以根據條件選擇執行

### if 語句
* 在執行語句前進行某些判斷。如果成立就執行，不成立反之。

```javascript!
if(條件){
    // 如果條件判斷為 TRUE，進入代碼塊執行功能
    codes...
}
```

### if...else...
* 如果條件為 true 執行 if 的代碼塊，false 則執行 else
```javascript!
if(條件){
    // 如果條件判斷為 TRUE，進入代碼塊執行功能
    code1...
}else{
    // 如果條件判斷為 FALSE，進入代碼塊執行功能
    code2...
    
}
```

### if...else if...else
* 多個條件判斷可以使用 else if 
* 由上而下依序執行條件判斷
* 如果全部條件都不滿足，則執行else
```javascript!
if(條件1){
    code1...
}else if (條件2){
    code2...
}else if (條件3){
    code3...
}else{
    code4...
}
```

### switch
* 條件分支語句
* 在執行時，switch後的條件表達式回和case中的數值做全等比較。
* 如果比較結果為 false，向下比較。
* 如果比較結果為 true，則開始執行case底下的代碼。完畢後向下繼續判斷。
* 加入 break，可以在判斷成立後終止判斷。
* 如果所有判斷結果都為 false，則執行 default。
```javascript!

swith(num1){
    case 表達式:
        code...;
        break;
    case 表達式:
        code2...;
        break;
    default:
        code3...;
        break; 
}
```

**參考視頻** 
[28 尚硅谷 JS基础 if语句（一） - YouTube](https://www.youtube.com/watch?v=e6whBhYJ0SE&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=28)
[29 尚硅谷 JS基础 if语句（二） - YouTube](https://www.youtube.com/watch?v=eQmU1V_gdXc&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=29)
[33 尚硅谷 JS基础 条件分支语句 - YouTube](https://www.youtube.com/watch?v=yBORt9P6sdE&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=33)


---


## 迴圈與循環

### for 迴圈
### while 迴圈 (無窮循環)
### 巢狀迴圈 (大陸用語:嵌套)
### break 和 continue



---

## Object 物件的操作
### 簡介
* 大陸的用語是**對象**，台灣的用語是**物件**
### 物件的方法 
> [color=#ff42dc] 學習完函數，才會理解對象中的方法。

```javascript!
// 創建一個對象
var obj = new Object();
obj.name = "王大明";
obj.sayName = function(){
    console.log(obj.name)
}
// 調用對象中的函數
obj.sayName(); // 調方法

// 函數也可以作為對象中的屬性
// 如果函數作為一個對象屬性保存，此時，此函數被稱為物件的方法
// 調用函數被稱為，調用物件的方法

document.write(); // 這個是調用 document object 的方法

// 其他撰寫物件方法

var obj2 = {
    name: "王大明",
    age: 18,
    sayName: function(){
        console.log(obj2.name)
    }
}
```

枚舉物件中的屬性
```javascript!
// for 會枚舉物件中的所有屬性
// n 會是 "name"、"age"、"sayName"
for(var 變量n in 對象obj2){
    console.log(n);
    // 取值
    console.log(obj2[n]);
}
```
==重點筆記==
* 函數可以作為物件的屬性
* 此屬性稱之前物件的**方法**
* 調用物件的方法就是調用物件之中的函數
* 物件有兩種寫法。因此，有兩種方法撰寫方式。

**參考視頻** [57 尚硅谷 JS基础 方法](https://www.youtube.com/watch?v=EZrQo8s2QfM&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=57)




---


## 函數式 Function
:::info
### 簡介 
* 函數也是一個==物件==。
* 函數可以用來封裝一些功能(代碼)，必要的時候可以拿來使用。
* 函數可以儲存一些代碼。
> [color=#ff42dc] 說明: 撰寫函數可以避免代碼複用，導致程式碼攏長。
:::
```javascript!
// 創建一個函數物件
var fun = new Function();
console.log(fun);        //回傳 空的 function
console.log(typeof fun); //回傳 function

// 封裝到函數中的代碼，不會立即執行，函數中的代碼，會在函數調用的時候執行
var fun = new Function("console.log('This is my first function.')");
//調用函數的語法，調用後，函數內的代碼會按造順序執行
fun(); 
// 函數就是一個物件，可以有物件的功能
fun.hello = "你好";
console.log(fun.hello);
```
通常不會使用以上的方式定義函數，會用下面方式

```javascript!
// 語法
function FunctionName([para1,para2,...,paraN]){
    // js code， you can write mutiple codes here...
    alert("!!!!")
    console.log("~~V~~") 
}
// 調用
FunctionName();

// 匿名函數方法 (效果和上面一樣，兩種都會用到)
// 用賦值語句的方式讓匿名函數被一個變數接住
var fun2 = function(){
    ....
}
```
**參考視頻** [51 尚硅谷 JS基础 函数的简介](https://www.youtube.com/watch?v=pFQPa-1BqNc&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=51)

### 函數的參數
```javascript!
// 函數的() 框框中可以傳遞參數
// 可以指定一個或多個形式參數(形參)
// 聲明後並不賦值
function sum(num1,num2){
    console.log(num1+num2)
};
// 可以在調用函數時在 ()指定實際參數(實參)
sum(5,3); // 5 對應 num1, 3 對應 num2
// 調用函數的時候，解析器不會檢查 (這個就是 JS 缺點)
sum("string",5)
// 多餘的實參不會賦值，多餘的對應的形參就是 undefined
sum("string",5,23,51,22)
```
**參考視頻** [52 尚硅谷 JS基础 函数的参数](https://www.youtube.com/watch?v=wtGopoF9Jwk&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=52)

多個變量打包傳入
```javascript!
// 將參數封裝在對象中
var obj = {
    name:"王大明",
    age: 18,
    gender: "男"   
}

function sayHello(o){
    console.log("你好" + o.name, "今年" + o.age + "。我是" + o.gender + "生")   
}
```
函數可以作為參數傳入
```javascript!
function fun(a){
    console.log(a)
}
fun(function(){})
```

**參考視頻** [54 尚硅谷 JS基础 实参可以是任何值](https://www.youtube.com/watch?v=yyAloB7_gqI&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=54)

==重點筆記==
* 參數可以放入任何類型的值。
* 參數可以是物件也可以是函數。

### 函數的返回值

```javascript!
// 創建一個函數計算三數合
// 計算完的東西想給其他功能使用，必須得傳出
// 可以用 ruturn 去接計算結果
function sum(a,b,c){
    console.log(a+b+c)
    var d = a+b+c;
    return d; // 如果不寫 return，返回就會是 undefined
}
// 調用函數，用變數去接
// 函數返回什麼，result 就會是什麼
var result = sum(1,2,3)
```

```javascript!
// 回傳一個 function
function fun3(){
    function fun4(){
        alert("fun4");
    };
    // 函數對象作為返回值
    return fun4();
}
```

==重點筆記==
* 撰寫 return 可以回傳 function 計算結果。
* return 可以是任意類型的值，string, number, etc...。
* 如果在function中不寫 return，回傳會是一個 **undefined**。
* return 可以是一個 object，也可以是函數。

**參考視頻** [53 尚硅谷 JS基础 函数的返回值](https://www.youtube.com/watch?v=uv76A71htKs&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=53)

**參考視頻** [55 尚硅谷 JS基础 返回值的类型](https://www.youtube.com/watch?v=xUUw0rvdmq4&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=55)

### 立即執行函數

```javascript!
// 函數寫完，立即調用，用誇號包住匿名函數
// 函數只會執行一次
(function(){
    console.log("Hello")
})();
```
**參考視頻** [56 尚硅谷 JS基础 立即执行函数](https://www.youtube.com/watch?v=_oRaYVoi7Es&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=56)


### THIS 概念

==重點整理==
* 每次調用函數用函數的時候，都會傳遞一個隱含的參數
* 此隱含參數就是 this, this 指向一個對象
* 這個對象稱為函數執行的上下文對象
* 根據函數調用方式不同，會指向不同的對象

1. 調用函數型式，this 永遠是 window
2. 調用方法形式，this 就是方法的對象

```javascript!
function fun(){
    console.log(this.name); // 此時是 window
};

fun(); // 函數形式調用
// 上面的調用等同於， window.fun()

var obj = {
    name: "王大明",
    sayNmae: fun
}

console.log(obj.sayName == fun); // true
obj.sayName(); // // 方法形式調用，此時是 object [obj]

```

**參考視頻** [61 尚硅谷 JS基础 this](https://www.youtube.com/watch?v=OyM9G71maw4&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=61)


### 函數的方法 call 及 apply
:::spoiler
123456
:::

---

## 數組 (Array)
:::info
### 簡介 
* 內建對象: 包含 object、function
* 數組也是一個對象，他和普通對象(object)功能類似，用來存儲數據。
* 普通對象用字串符作為屬性名 (ex. obj.name)。
* 數組以**數字** 作為索引來操作元素。
* 索引: 從 0 開始。
* 數組儲存的效能比對象好
:::

普通物件

| 屬姓名 | 屬性值  |
| ------ | ------- |
|    name    |   Mr.John      |
|    age    |      15   |
|   address | taipei |

數組物件

| index | value |
| ----- | ----- |
| 0     |  text1  |
| 1     |  text2  |
| 2     |  text3  |

創建數組對象
```javascript!
var arr = new Array();
console.log(typeof arr); // 回傳 object

// 添加元素
// 語法: arr[index] = value

arr[0] = "text1";
arr[1] = "text2";
arr[2] = "text3";

// 讀取數組中的元素
// 語法: arr[index] 

console.log(arr[0])
console.log(arr[3]) // 讀取不存在的索引，不報錯，返回 undefinded

// 獲取數組長度
// arr 中有一個方法可以調用
console.log(arr.length);

arr[10] = "text10";
// 非連續數組，會獲取最大索引 + 1, 上面的 length = 11
console.log(arr); // 他會給你 text1,text2,text3,,,,,,,,text10
// 盡量不要寫非連續數組

// 修改 arr.length，會刪除多餘元素
arr.legth = 4;

// 往最後位置添加元素的方法
// 語法: 數組[數組.length] = value
arr[arr.length] = "value"
```

==重點整理== 
1. Array 可以調用 length 方法。獲取數組的長度
2. 長度會受到非連續數組影響，盡量不要使用非連續數組

**參考視頻** [70 尚硅谷 JS基础 数组简介](https://www.youtube.com/watch?v=uLnNmJcVfUk&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=70)

### 數組字面量
使用字面量的方式創建數組
```javascript!
// 語法: []
var arr = [];

// 使用字面量創建數組時，可以在創建時就指定元素
var arr2 = [1,2,3,4,5]

// 使用構造函數創建數組時，可以同時添加元素
var arr2 = new Array(10,23,44);

// 創建一個數組，只有一個元素
var arr3 = new Array(10);
// 這時候會生成一個長度為10的數組

// 元素是函數、物件
var arr4 = [function(){console.log}, {"name":"John"}]

```
==重點筆記==
1. 創建數組有不同方式
2. 數組內可以是任何類型的元素、數組、函數，也可以是物件

**參考視頻** [71 尚硅谷 JS基础 数组字面量](https://www.youtube.com/watch?v=XU1RyQ4nseI&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=71)


### 數組常用的四個方法
1. arr.push(元素1,元素2...): 在數組的**末尾**添加一個或多個元素，返回數組的新長度。
2. arr.pop(): 刪除數組最後一個元素並返回數組的最後一個元素。
3. arr.unshift(元素1,元素2...): 在數組的**開頭**添加一個或多個元素，返回數組的新長度。
4. arr.shift(): 刪除數組第一個元素，並返回數組的第一個元素。

**參考視頻** [72 尚硅谷 JS基础 数组的四个方法](https://www.youtube.com/watch?v=XdOVZZx4cFw&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=72)

### 數組的遍歷
```javascript!
// 讀取
var arr = [...];
for(var i=0; i<arr.length; i++){
    console.log(arr[i])
}           
```
### forEach語法
* 一般使用for循環來遍歷數組
* JS 提供一個方法 forEach
* forEach 只有支持 IE8 以上
* 需要一個函數作為參數傳入
* 這種函數，由我們創建，但不由我們調用，稱為**回調函數**。
* 數組有幾個元素，函數執行幾次，每次執行時，會將遍歷的元素，會當實參傳遞進去函數。可以定義形參來讀取。
```javascript!
// 讀取
var arr = [...];
arr.forEach(function(value,index,object){   
    console.log(value)
})         
```

### slice及splice
1. arr.slice(start,end): 從已有的數組返回選定的元素。
    start: 開始位置的索引, end: 結束位置的索引。不會改變原本的數組。
2. arr.splice(start,數量,新插入的值1,新插入的值2...): 從已有的數組返回選定的元素進行刪除。會對原本數組要成影響。第三個參數可以傳入新的函數。

### 數組去除重複
```javascript!

var arr = [1,1,2,2,2,4,5,5,2,6,6,9]

for(var i=0; i<arr.length; i++){
    console.log(arr[i])
    // 從下一個開始比，當前元素後面的所有元素
    for (var j=i+1; j<arr.length; j++){
        console.log("---->",arr[j])
        // 判斷 arr[i] arr[j] 是否相等
        if(arr[i]==arr[j]){
            // 出現重複函數，則刪除 j
            arr.splice(j,1)
            // 刪除後，後面的元素會自動補位，往前移動得數字就不會比到
            j--; // 再比一次
        }
    }
}

console.log(arr)
```

### 數組的剩餘方法
1. var arr3 = arr.concat(arr2): 連接兩個數組，將新的數組返回，該方法不會影響原數組。 
2. var result = arr.join("-") : 該方法可以將數組轉換為一個字符串，該方法不會影響原數組。 * 類似python中 "".join(list) 方法。默認","。
3. arr.reverse(): 可以反轉數組，會影響原數組。
4. arr.sort(): 排序原本數組，會影響原數組。默認 unicode 排序。如果arr中是數字，還是以 unicode排序，會是錯誤的結果。

```javascript!
// sort 可以傳入參數去定義排序規則
// 需要傳入兩個形參
// 瀏覽器會分別使用數組中的元素作為實參去調用回調函數
// 使用哪個元素調用不確定，但 a 一定再 b 前面
// 瀏覽器根據回掉函數的返回值，決定順序， 返回 > 0，元素會交換
// 瀏覽器根據回掉函數的返回值，決定順序， 返回 < 0，元素不會交換
// 瀏覽器根據回掉函數的返回值，決定順序， 返回 = 0，認為兩個元素相等，也不會交換
arr = [5,4]
arr.sort(function(a,b){
    // 前面比後面大，換位
   if (a > b){
       return 1
    // 後面比前面大，不換位
   }else if (a < b){
       return  -1
   }else {
       return 0 // 數字相等
   }
})

arr.sort(function(a,b){
   return a - b 
    // 前面值比後面值大，會是正數，交換位置
    // 前面值比後面值小，會是負數，不交換位置
    // 前面值比後面值相同，會是0，不交換數字
})
```
**參考視頻** [78 尚硅谷 JS基础 数组的剩余方法](https://www.youtube.com/watch?v=cWuqNdzYnG0&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=78)


---

## JavaScript 操作 HTML 元件的方式

:::info
### DOM 簡介
* DOM 是 Document Object Model 的縮寫。
* JS 通常是通過 DOM 對於 HTML 文檔進行操作。
* Document 文檔: 表示 HTML網頁文檔。
* 對象: 網頁上面的每一個部分(網頁上的每一個東西)都轉換為一個對象。
* 模型: 表示對象之間的關係，方便我們獲取、操作對象。
* 操作DOM: JS通過操作網頁上的對象，影響HTML的呈現。
:::

### 模型
以下是一個常見的 HTML文檔
```htmlmixed!
<html>
    <head>
        <title>網頁的標題</title>
    </head>
    <body>
        <a href="xxx.html">超連結</a>
    </body>
</html>  
```
模型體現出節點與節點之間的關係，有父子、祖先的關係。
```mermaid
graph TD;
文檔-->html;
html-->head;
html-->body;
head-->title;
body-->a;
a-->文本節點;
title-->文本節點;
```

==重點筆記==
* html 中的元件彼此是有關係的。
* 節點 Node 是網頁的基本組成成分。
* html 中的每個部分，標籤、文本、註釋、整個文檔，都是節點。

### 節點的類型
雖然說，網頁中的每個部份，都是結點。但是他們的具體類型是不同的。節點不同，屬性方法也不同。常用的節點分成四類:

1. 文檔節點: 整個 HTML 文檔
2. 元素節點: HTML 文檔 中的 HTML 標籤
3. 屬性節點: 元素的屬性
4. 文本節點: HTML標籤中的文本內容

:::danger
還沒閱讀完畢...
:::


**參考視頻** [91 尚硅谷 JS基础 DOM简介](https://www.youtube.com/watch?v=3D-3Bp7OvOE&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=91)


