---
# System prepended metadata

title: JS(3/10) Day 14 五倍紅寶石(第八屆共筆)(2021/7/15)
tags: [JavaScript]

---

# JS(3/10) Day 14 五倍紅寶石(第八屆共筆)(2021/7/15)
## 函式：
引數帶到參數會變變數。
參數寫在 function 裡 JS 會自動幫你在 function 內宣告，而且也不會洩漏出去。
如果要印出沒有定義的變數會出錯(not define)。
單純賦值的話會往外找有沒有一樣名稱的變數，沒有的話 JS 就直接在全域物件(最大泡泡)幫你宣告一個。
在JS裡，參數跟引數的數量不一樣不會出錯，別的程式語言則會。

引數 < 參數：沒被給到引數的參數會變 undefined。
引數 > 參數：多給的引數沒作用，不會印出。

function 在設定參數時也可以設定他的預設值。
當他沒有給引數時，他會自動帶入預設值。
ex:console.log()的預設值就是換行。

在function內輸入 console.log(arguments) 會以陣列方式直接印出所有引數。

寫code時盡量不要使用 ! ，因為要轉個彎會比較難理解。

a() = 呼叫a這個東西所指向的 function，
()只能用來呼叫 function ，若 a 指向的東西不是 function 會出錯。

---

### 三種 function 寫法：
1. Function statement (Function declaration)： 
function a( ) { }
2. Function expression：
let b = function a( ) { } 
3. Arrow function expressions：
let b = ( ) => { }
- 箭頭函式跟前面兩個函式是不同的函式，不是簡寫而已。
  差異可參考:[Arrow function expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
- 箭頭函式不能幫他取函式名，只能幫他取變數名字，不然會出錯。
- let b 可以省略，會變成匿名函式。
- ()內若只有一個參數可省略()，但不建議。
- 若{}裡面只有一行可省略{}，並省略 return，但如果寫了{}就一定要加 return。
- 沒有自己的 this。
- 不能用 new 來建立。
- 沒有 .prototype 屬性。
- 當成建構物件來使用時，{}外面要再加()才能運作。
- => 一定要跟在()後面，可以空格但不能換行。

第一種的 a 不可省，第二種的可以省，省略後稱做匿名函式，因為一省略就沒名字呼叫啦，二前面已經宣告過一個 b 變數，之後的呼叫都靠他就好。(Kyle Simpson 大師很注重裡面的 function 名稱不能省略，有興趣的可以參考他的書。)

---

### function也會變數提升：
除了用 var、let、const 宣告會有變數提升的效果外，**Function declaration**也會這招，Function expression 跟 Arrow 因為是用變數宣告的關係，所以用法跟變數提升一樣。
其中 Function declaration 的提升跟變數的提升有一個地方不一樣。

回憶一下之前的變數提升有兩階段：
1. 建立期：JS會先分配記憶體給宣告的變數及函式，其中函式又會比變數優先被宣告，
   在建立期會做兩件事情：
   1A：註冊名稱 = 建立罐子，JS會執行宣告變數，但不會給變數的值。
   1B：初始化 = 給他空氣，因為沒有值的關係，這個變數的值會是undefined。
2. 執行期：由上而下一行一行執行程式碼
   在執行期會依照上至下的順序做兩件事情：
   2A：把宣告變數裡的值指定給變數。
   2B：執行函式。

Function declaration 的提升在建立期一樣會做1A、1B，但是不一樣的地方在於他還會在建立期多做2A。為的是方便輸出，因為函式之間常常互相呼叫，可以避免因為 b 函式寫在 a 函式下方的時候，用 a 無法呼叫 b 的狀況出現。
```js=
// 可正常執行
function a( ) {b() }
function b( ) { }
```

---

### scope chain：
指派的特權，如果在函式內的變數只有指派而沒有宣告(ex: a = 1)，會往函式外去找這個變數有沒有宣告，都找不到的話JS最後會直接在全域物件裡幫你宣告一個。(別的程式語言不會這樣)
若最後有找到變數會污染他，讓他變成自己的值。

全域物件：node.js 叫 global，瀏覽器叫 window。
console.log 的全名應該叫 window.console.log。

---

### 變數存活範圍：
function 裡的變數宣告只能活在那個 function 裡，執行完泡泡就會破了。
function{}可以關住：var、let、const。
{}只能關住：let、const。
for(var...){} 會溢出到外面。
for(let...){} 因為有{}所以會鎖在 scope 裡。
```js=
// 建議寫法：把宣告 result 拉到 for 迴圈外面並且不指定值，才不會被鎖在裡面。
let age =20
let result

if (age >= 18) {
  result = "已成年"
} else {
  result = "未成年"
}
console.log(result)
```
---

## 物件：
```js=
const hero = {name(key):"悟空"(value)}
可以用 console.log(hero.name)或是
      console.log(hero["name"])來呼叫
```

### Xmind：
[JavaScript指令](https://www.xmind.net/m/eYMwp5)
---
###### tags: `JavaScript` 