# 第五週共筆筆記 - <br> 11/2 核心篇第五堂:函式
###### tags: `核心篇`、`六角學院`、`2022JS直播班`
[講義連結](https://hackmd.io/iQF41M3DR3qEesvPcMIzzg)
## 共筆簽到區
## 正課開始!~~~~
### 本日知識點
#### 函式本身由 function定義
---
1 可以執行片段程式碼
2 可以重複的呼叫
3. 可以傳入不同的參數,
```javascript!
function callSomesone(somesone){
console.log(`嘿,那個誰${someone} 來一下`);
}
callSomeone('小明');
//函式也是一個物件
callSomeone.myName = '這是函式';
console.log.dir(callSomeone);
```
>定義函式 要小寫開頭
4. 限制作用域
```javascript!
function callSomesone(somesone){
const who = '漂亮阿姨'
console.log(`嘿,那個誰${someone} 來一下`);
}
callSomeone('小明');
//函式也是一個物件
callSomeone.myName = '這是函式';
console.log.dir(callSomeone);
```

5. 函式可以回傳值
```javascript!
function callSomeone(someone) {
const who = '漂亮阿姨'
return 黑,我是 ${who},那個 ${someone} 來一下
}
const text = callSomeone('小明')
console.log(text + '這是其他的字串');
```
案例:需要一個函式,他可以相乘
1. 先將可以運作的程式碼寫出來
```js!
let num = 2;
let num2 = 4;
let result = num * num2;
console.log(result);
```
2. 將運算的部份抽離
```js!
let num = 2;
let num2 = 4;
let result;
function multiplay(params) {
result = num * num2;
}
multiplay();
console.log(result);
```
3. 參數及 return
```js!
let num = 2;
let num2 = 4;
let result;
function multiplay(a, b) {
result = a * b;
}
let result = multiplay(num, num2);
console.log(result);
```
函式陳述式 一定要有名字
### 一級函式
一個特性、一個概念
1. 函式可以作為變數(函式表達式)

#### Callback Function
傳來傳去會一直改名字,先專注看函式本身
2.函式可以做為參數使用
```javascript!
cnost fn = function(callbackFunction){
callbackFunction()
}
fn(function({
console.log(123);
}))
```
```javascript!
function fn(callbackFumction){
var a = "小名";
var b = "杰倫";
callbackFunction(a,b) //需要使用 fn 函式先做一次使用
}
fn(function(x,y) {
console.log(`${x}, ${y} 是好朋友`);
})
```
### forEach 的Callback function 寫法
```javascript!
fn(["小明", "杰倫", "漂亮阿姨"], (item, i) {
console.log(item, i);
})
// 待補
```


3. 函式可以作為回傳值
```javascript!
function fn(){
return funciton() {
console.log("這是回傳的函式");
};
}
fn()();
```

### 高階函式
一個技法:有一級函式的特性就有高階函式的寫法!
如果沒有高階函式,函式執行方式會被限制
1. 函式作為參數傳入 (如果JS沒有高階函式的技法時可以這樣寫)
```javascript!
```

2. 輸出一個函式
```javascript!
function discountTool(price, value) {
return price * value;
}
const breadPrice = discountTool(100, 0.8);
console.log(breadPrice);
// output: 80
const cookiePrice = discountTool(80, 0.7);
console.log(cookiePrice);
// output: 56
```

### 高階函式技巧
1. 傳入的是價格
```javascript!
function discountTool(price) {
const originPrice = price;
return function (value) {
return originPrice * value;
}
}
const breadPrice = discountTool(100);
console.log(breadPrice); // 會印出一個函式
console.log(breadPrice(0.8));
console.log(breadPrice(0.7));
```
#### 1. 閉包:closure (一種高階函式的技法)
內層函式可以取得外層函式作用域內的變數
如何形成?
特性?
閉包就是內層函,是可以取得外層函式作用域內的變數
```javascript=
function fn(){
var someVariable = 100;
}
```

#### 2. 透過高階函式特性(回傳函式),將作用域內的變數儲存不被釋放
```javascript!
function sellBread(){
//這裡宣告的變數,外部存取不到
const breadPrice = 100;
let count = 0;
return function(c){
//到底賣了多少,外層也存取不到
count +=c;
console.log(`今天賣出了${count} 麵包,總共賺了 ${breadPrice * count} 元`);
}
}
const todayTotal = sellBread();
cnosole.log(todayTotal);
todayTotal(1);
todayTotal(10);
todayTotal(10);
```



#### 3. 私有方法
錢錢,可以存錢、可以花錢、可以取得有多錢的值
```javascript!
function storeMoney (initValue) {
let money = initValue;
return {
increase: function(price) {
money += price;
},
decrease: function(price) {
money -= price;
},
getValue: function(price) {
return money;
}
}
}
const 卡斯伯錢包 = storeMoney(1000);
console.log(卡斯伯錢包); //物件
卡斯伯錢包.increase(1000);
卡斯伯錢包.decrease(500);
console.log(卡斯伯錢包.getValue());
const rayWallet = sotreMoney(50000);
rayWallet.increase(30000);
rayWallet.decrease(20000);
console.log(rayWallet.getValue());
```
