---
# System prepended metadata

title: JavaScript 基礎篇
tags: [JavaScript]

---

###### tags: `JavaScript`

# JavaScript 基礎篇
## 變數(Variable)與值(Value)

- 宣告變數的方法：let、const、var
    - let、const 宣告的變數不會存在於 windows 裡面，使用 this 要注意 [範例](https://codepen.io/nielsen_dch/pen/vYJvYad?editors=1111)。

- 基本型別 ( primitives types ) 介紹
    1. 字串 ( String )
    2. 數字 ( Number )
    3. 布林 ( Boolean )
    4. undefined - 尚未被賦予值
    5. null - 有被賦予值，但是是空值
    6. Symbol 
- 型別操作方法
> 除了基本型別外，後面還會講解物件型別，例如陣列(array)與物件(object)

## 比較運算子與邏輯運算子
```javascript=
// 比較運算子 >、=、<=
let a = 1;
let b = 2;
let c = 1;
a < b // true
a > b // false
a >= c // true
a <= c // true

// 比較運算子 ==、===、!=、!==
// == 的時候不會判斷轉型別，所以只要字串內容跟數字是一樣就 true
// ==== 的時候會先判斷轉型別再比較內容，所以只要型別或字串內容不一樣就 false
let a = '1'
let b = 1;
a == b // true
a === b // false
a != b // false
a !== b // true

// 邏輯運算子 &&、||
// 如果有多筆判斷式用 && 代表所有的判斷都要符合
// 如果有多筆判斷式用 || 代表只要有一個符合就好
let a = 1;
let b = 2;
let c = 1;
a === c && b > a // true
a === c && b < a // false
a === c || b === a // true
a === c || b <= a // true
```

# JavaScript 操作語法

## parseInt()字串轉數字

```javascript=
// 轉換型別成功，如果變數開頭是數字後面是字串會取前面的數字
let a = '34';
console.log(typeof a); // string
console.log(typeof parseInt(a)); // number

let b = '50ertyetddgv';
console.log(parseInt(b)); // 50

let c = '0.55';
console.log(parseInt(c)); // 0

// 轉換型別錯誤，如果變數開頭是中英文字或特殊符號會出現 NaN
let d = 'ab34c';
console.log(parseInt(d)); // NaN

let e = '!99';
console.log(parseInt(e)); // NaN

```

---

## toString() 數字轉字串方法

```javascript=
let a = 34;
console.log(typeof a); // number
console.log(typeof a.toString()); // string

let b = 50;
console.log(b.toString()); // "50"

let c = 0.55;
console.log(c.toString()); // "0.55"
```

---

## toLowerCase() 字串轉小寫

```javascript=
const str1 = 'This Is A Apple';
console.log(str1.toLowerCase()) // this is a apple

const str2 = '你好嗎 NICK';
console.log(str2.toLowerCase()) // 你好嗎 nick

const str3 = 'DFGd4eg@112dFHf~fHJTg';
console.log(str3.toLowerCase()) // dfgd4eg@112dfhf~fhjtg
```

---

## toUpperCase() 字串轉大寫

```javascript=
const str1 = 'this is a apple';
console.log(str1.toUpperCase()) // THIS IS A APPLE

const str2 = '你好嗎 Nick';
console.log(str2.toUpperCase()) // 你好嗎 NICK

const str3 = '@2f304ge4hgjur54!';
console.log(str3.toUpperCase()) // @2F304GE4HGJUR54!
```

---

![](https://i.imgur.com/n6TzPVG.png)

## innerHTML 設定/取得標籤
innerHTML 特性會清空標籤內的內容，在塞入自訂義的內容
```javascript=
<h1 class="titleClass">
  <a href="#">title</a>
</h1>
<script>
  var el = document.querySelector('.titleClass').innerHTML;
  console.log(el); // <a href="#">title</a>
</script>
```

innerHTML 搭配 for 迴圈
```javascript=
<ul class="list"></ul>
<script>
  var farms=[
    {
      farmer:'卡斯柏',
      dogs:['張母是','小白'],
    },
    {
      farmer:'老張',
      dogs:['欣欣'],
    },
  ]

  var el = document.querySelector('.list');
  var len = farms.length;
  var str = ''; // 累加用
  for(var i=0;i<len;i++){
    if(farms[i].dogs.length > 1){
      var content = `<li>第 ${i + 1} 農場的主人是 ${farms[i].farmer} ，她的寵物有 ${farms[i].dogs.length} 隻，分別叫做 ${farms[i].dogs}</li>`;
    }else{
      var content = `<li>第 ${i + 1} 農場的主人是 ${farms[i].farmer} ，她的寵物有 ${farms[i].dogs.length} 隻，叫做 ${farms[i].dogs}</li>`;
    }
    str+=content;
  }
  el.innerHTML = str;
</script>
```
結果如下
- 第 1 農場的主人是 卡斯柏 ，她的寵物有 2 隻，分別叫做 張母是,小白
- 第 2 農場的主人是 老張 ，她的寵物有 1 隻，叫做 欣欣

---

## createElement 新增 HTML 標籤

```javascript=
<h1 class="title">
  <em>title</em>
</h1>

<script>
// createElement() 插入 HTML 標籤
// appendChild 動態插入子節點
var str = document.createElement('em'); // 準備插入 em 標籤
str.textContent = '1234'; // em 標籤內容
// 目前 str = <em>1234</em>
document.querySelector('.title').appendChild(str);
</script>
```
結果如下
![](https://i.imgur.com/hAk8SWe.png)

createElement 搭配 for 迴圈
```javascript=
<ul class="list"></ul>
<script>
  var farms=[
    {
      farmer:'卡斯柏',
      dogs:['張母是','小白'],
    },
    {
      farmer:'老張',
      dogs:['欣欣'],
    },
  ]

  var el = document.querySelector('.list');
  var len = farms.length;
  for(var i=0;i<len;i++){
    var str = document.createElement('li');
    if(farms[i].dogs.length > 1){
      str.textContent = `第 ${i + 1} 農場的主人是 ${farms[i].farmer} ，她的寵物有 ${farms[i].dogs.length} 隻，分別叫做 ${farms[i].dogs}`;
    }else{
      str.textContent = `第 ${i + 1} 農場的主人是 ${farms[i].farmer} ，她的寵物有 ${farms[i].dogs.length} 隻，叫做 ${farms[i].dogs}`;
    }
    el.appendChild(str);
  }
</script>
```
結果如下
- 第 1 農場的主人是 卡斯柏 ，她的寵物有 2 隻，分別叫做 張母是,小白
- 第 2 農場的主人是 老張 ，她的寵物有 1 隻，叫做 欣欣

---

## textContent 設定/取得標籤裡的內容

```javascript=
<h1 class="titleClass">
  <a href="#">title</a>
</h1>
<script>
  var el = document.querySelector('.titleClass a');
  console.log(el.textContent); // title
</script>
```

---

## setAttribute 設定屬性
setAttribute('屬性', '修改成')
> ex: setAttribute('href', 'https://tw.yahoo.com/')

他會將屬性的清空再加入你要修改的值，所以如果是 class 會變成單一個

> 原本：< div class="strId adwd">123456789< /div>
> 
> 在 JS 加入：
> var el = document.querySelector('.strId');
> setAttribute('class', 'abc')
> 
> 結果：< div class="abc">123456789< /div>
```javascript=
<style>
    .strId{
      color: red;
    }
</style>
<h1 class="titleClass">
    <a href="#">title</a>
</h1>
<div class="str">123456789</div>
<script>
  var el = document.querySelector('.titleClass a');
  var el2 = document.querySelector('.str');
  el.setAttribute('href','https://tw.yahoo.com/'); // 修改 a 連結
  el2.setAttribute('id','strId'); // 新增 id
</script>

```
![](https://i.imgur.com/uqOXWF6.png)


---

## getAttribute 取得屬性
getAttribute('屬性')
> ex: getAttribute('href')

```javascript=
<style>
    .strId{
      color: red;
    }
</style>
<h1 class="titleClass">
    <a href="https://123.com">title</a>
</h1>

<script>
    var el = document.querySelector('.titleClass a').getAttribute('href')
    console.log(el) // https://123.com
</script>

```

---

## classList.add() 新增 class

```javascript=
  <div id="id" class="a1">請看 class name</div>
  
  <script>
    // classList.add 新增
    document.getElementById("id").classList.add('a2');
    // classList.add 新增多筆
    // document.getElementById("id").classList.add('a2', 'a3', 'a4');
  </script>
```

![](https://i.imgur.com/QHQ2QiZ.gif)

---

## classList.remove() 移除 class

```javascript=
  <div id="id" class="a1 a2 a3">請看 class name</div>
  
  <script>
    // classList.remove 移除
    document.getElementById("id").classList.remove('a1');
    // classList.remove 移除多筆
    // document.getElementById("id").classList.add('a2', 'a3', 'a4');
  </script>
```

![](https://i.imgur.com/BvEO56F.gif)

---

## classList.contains() 判斷 class

```javascript=
  <div id="id" class="a1">請看 class name</div>
  
  <script>
    // classList.contains 判斷是否有對應的 class
    if (document.getElementById("id").classList.contains('a1')){
      console.log('Yes');
    } else {
      console.log('No');
    }
  </script>
```

![](https://i.imgur.com/iLotlCj.gif)

---

## classList.toggle() 切換 class

- 沒有 a2 的時候
```javascript=
  <div id="id" class="a1">請看 class name</div>
  
  <script>
    // classList.toggle 當有對應的 class 就移除，沒有就增加
    document.getElementById("id").classList.toggle('a2');
  </script>
```
![](https://i.imgur.com/6tCBLZ3.gif)

- 有 a2 的時候
```javascript=
  <div id="id" class="a1 a2">請看 class name</div>
  
  <script>
    // classList.toggle 當有對應的 class 就移除，沒有就增加
    document.getElementById("id").classList.toggle('a2');
  </script>
```

![](https://i.imgur.com/Irbd9ID.gif)

---

## classList function

```javascript=
  <div id="id" class="a1 a3">請看 class name</div
  
  <script>
    function hasClass(el, className) {
      if (el.classList) {
        return el.classList.contains(className);
      } else {
        return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
      }
    }
          
    function addClass(el, className) {
        if (el.classList) {
          el.classList.add(className);
        } else if (!hasClass(el, className)) {
          el.className += " " + className;
        }
    }

    function removeClass(el, className) {
        if (el.classList) {
          el.classList.remove(className);
        } else if (hasClass(el, className)) {
          var reg = new RegExp('(\\s|^)' + className + '(\\s|$)');
          el.className=el.className.replace(reg, ' ');
        }
    }
    let el = document.getElementById('id')
    // 新增 a2
    addClass(el, 'a2')
    // 移除 a3
    removeClass(el, 'a3')
    // 判斷
    console.log(hasClass(el, 'a1')); // true
  </script>
```
![](https://i.imgur.com/fFbHqzE.gif)


# JavaScript 函式

## 函式陳述式 & 函式表達式差別
### <font color="#f00">函式陳述式</font> 呼叫的時候可以不用按照順序擺放，因為有提升（Hoisting）所以都可以正常執行
```javascript=1
console.log(numA(2)); // 4
function numA(x){
    return x * x;
}
console.log(numA(2)); // 4
```

### <font color="#f00">函式表達式</font> 是將函式賦予到變數上，所以一定要按照程式碼讀取的順序排，不然會出錯

- 錯誤的方式
```javascript=1
console.log(numA(2)); // Identifier 'numA' has already been declared
const numA = function (x){
    return x * x;
}
```

- 正確的方式
```javascript=1
const numA = function (x){
    return x * x;
}
console.log(numA(2)); // 4
```

## 函式陳述式、函式表達式、箭頭函式使用方式
```javascript=1
// 函式陳述式
function numA(x){
    return x * x;
}

// 函式表達式
const numB = function (x){
    return x * x;
}

// 箭頭函式
const numC = (x) => {
    return x * x;
}
// 箭頭函式縮寫-沒有參數
const numD = () => '沒有參數';
// 箭頭函式縮寫-單一參數
const numE = x => x * x;
// 箭頭函式縮寫-多個參數
const numF = (x,y) => x * y;


console.log(numA(2)); // 4
console.log(numB(2)); // 4
console.log(numC(2)); // 4
console.log(numD()); // 沒有參數
console.log(numE(2)); // 4
console.log(numF(2,3)); // 6

```