## 會議記錄
導讀:奕洲
時間:2025/5/7
範圍:JavaScript基礎介紹ch2-21~ch2-43
# 函式Function
* 函式是指將一或多段程式指令包裝起來,可以重複使用,也方便維護
除了基本型別以外的都是物件,函式也是物件的一種
* 輸入(參數)->函數->回傳值(結果)
* 函式宣告
最簡單是透過function來宣告一個函式
* 使用function關鍵字來創造一個函式
* `function doubleTheNumber (x){`
`return x * 2;`
`}`
(x)將此函式即將接收的參數放置於括號內
* return
當我們定義function時,可以讓它有回傳值,也可以不回傳,
端看設計需求,使用位置只能在function裡
一般來說.需要回傳值的function就像自動販賣機,
零錢投下去,商品出口處會掉出(return)我們指定的商品;
不需要回傳值的funciton就像捐獻箱(順手捐發票))
* 透過return決定回傳內容
return 不一定要存在於函式的內容中,只不過沒有使用return,或是return後面沒有任何要回傳的值,JavaScript會回傳undefined,所以可以把一個函式的回傳的預設值設置為undefined
* console.log
可以用來debug或檢視目前的計算結果、狀態,
使用位置不限於function裡或是全域範圍
## 函式執行
* doubleTheNumber(10)
在函數名稱後面加上括號來呼叫(invoke)函式
要傳進這個函式的值(引數)
## 函式何時結束
* return之後的任何內容都不會被執行
* `function doubleMe(x){`
`return x * 2;`
`x = x + 3` `在return後面故不執行`
`}`
`doubleMe(2);` `//4`
## ES6 箭頭函式(Arrow function)
* 宣告function
* `function test(n) {`
`return n`
`}`
* `const test = function(n) {`
`return n`
`}`
* 語法可以將function省略掉
`const test =(n) => {`
`return n`
`}`
*不需要參數的時候,前面的小括號()是不能省略的
`const test = () => {`
`return n`
`}`
* 如果只有一個參數
`const test = n => {`
`return n`
`}`
* syntax sugar語法糖 把東西包裝好

* 作用域(Scope)
* 閉包(Closure)
# JavaScript語法
## 敘述式(Statement)
* 執行某個動作,像是**變數的宣告、賦值、迴圈和if判斷式**
* `var foo;`
## 運算式(Expression)
* 會產生一個值,像是**呼叫function時的參數(arguments)**
或是透過 = 賦值時,在 =「右側」的部分都屬於運算式的部分
* `var a = 10 * 10;`
* **運算式由運算子(operator)和運算元(operand)組成**
運算式中會提供一些數值給「運算子」進行運算,得到運算結果
### 運算子
* 算術運算子(Arithmetic Operators)
* 一元運算子(Unary operator) + - x /
單單一個數值可以進行運算
不是數字型態的值,先透過Number()的方法嘗試轉型
* `var a = "+10";`
`var b = ""-10";`
`var c = "Hello";`
`console.log(a);` `//10`
`console.log(b);` `//-10`
`console.log(c);` `//NaN`
* 利用+將其他型別轉型為數字
`+true` `//1`
`false` `//0`
`+null` `//0`
`+function(val) {` `return val;` `}` `//NaN`
* 或是用!將數值轉為布林值
* 遞增++ 遞減--
* 二元運算子(binary operator) + - x /
* 三元運算子(ternary operator)
* 指派運算子(Assignment Operators)
* 「=」指派運算子 右邊的值指派給左邊的變數
undefined:已宣告變數,尚未賦值
null:變數可能曾經有值,可能沒有值,現在沒有值
* 比較運算子(Comparison Operators)
* 邏輯運算子(Logical Operators)
### 常用二元運算子介紹
#### 算術運算子(Arithmetic Operators)
四則運算
* 「+」加法運算子 加法
* 數值型別+字串
* **3 + "4" => "34"**
* **100 + "100" => "100100"**
* **100 + "ABC" => "100ABC"**
* **"ABC" + "XYZ" => "ABCXYZ"**
運算元兩邊的數值不是數值型別,觸發「強制轉型」(Coercion)
JavaScript會嘗試將運算子兩邊的數值強制轉成同樣型別
* 數值型別+undefined
* **3 + undefined => 3 + NaN =>NaN**
* **123 + undefined => NaN**
只要其中一邊的數值是undefined,
JavaScript會將undefined轉成數字型別NaN
* **"abc"+ undefined => "abcundefined"**
當其中一邊為字串,另外一端被自動轉型為字串,連接在一起
* 數值型別+null
* **123 + null => 123**
* **"123" + null => "123null"**
與null相加,JavaScript會將null轉成數字型別0
JavaScript會將undefined轉成數字型別NaN
null與undefined是透過String()分別轉為"null"與"undefined"
* 數值型別+物件
* **3 + {} => 3 + "[object Object]" => "3[object Object]"**
其中一邊為物件,JavaScript會先嘗試將物件轉成字串
一般轉型時並不會顯示完整的物件細節,只會得到"[object Object]"的字串,這是JavaScript的預設行為轉成字串後,運算式就會以數值型別與字串型別相加處理
* Infinity
* **Infinity + Infinity =>Infinity**
* **-Infinity + -Infinity =>-Infinity**
* **-Infinity + Infinity =>NaN**
* number,boolean,object情況下,轉型會呼叫.toString的原型方法
取的對應的字串
* 運算式中由上而下,由左而右讀取,先乘除後加減
* `var num1 = 10;`
`var num2 = 100;`
`var str = ("10加100的數字會是"+num1+num2);`
`10加100的數字會是10100`
* 使用小括號
`var num1 = 10;`
`var num2 = 100;`
`var str = ("10加100的數字會是"+(num1+num2);`
`10加100的數字會是110`
* 「-」減法運算子
* **10 - 5 => 5**
* **10 - "4" => 10 - 4 => 6**
強制轉型的時機,其型別不是數值型別的時候,
JavaScript會直接嘗試將該數值轉為數值型別
* **10 - "4a" => 10 - NaN => NaN**
轉型失敗,跟加法運算子和undefined一起運算得到同樣NaN的結果,
**因為NaN與任何數值運算都會得到NaN**
* Infinity
* **Infinity - Infinity => NaN**
* **-Infinity - -Infinity => NaN**
* **-Infinity - Infinity => -Infinity**
* **Infinity - -Infinity => Infinity**
* 基本型別(string,boolean,undefined與null)
* **100 - "50" => 50**
* **100 - "abc" => NaN**
其中一方為基本型別但不是數字,
會先透過Number()嘗試將數值轉為數字再計算
* **100 - false => 100**
false經過 Number()轉型成數字,會變成0
* **100 - true => 99**
true 經過 Number()轉型成數字,會變成1
* **100 - undefined => NaN**
JavaScript會將undefined轉成數字型別NaN
* **100 - null =>100**
與null相減,JavaScript會將null轉成數字型別0
* 物件型別
透過valueOf()的方法求得相對應的數值,得到NaN,結果為NaN
如果物件沒有valueOf(),則用 .to String先轉成字串後,
再以Number()嘗試將數值轉為數字後再計算
* 「 / 」除法運算子
* **100 / 10 => 10**
被除數為0的情況下
* **10 / 0 => Infinity**
除法的結果是無限大,Infinity依然是數值型別,特殊情況才會出現,
超過JavaScripts能表示的數字範圍,就會出現Infinity,
所以有可能有+Infinity和-Infinity
* **-10 / 0 => -Infinity**
* **0 / 0 => NaN**
* 「 * 」乘法運算子
* 超出JavaScript數值範圍,得到無限大,情況少見
次方運算的方法Math.pow
10的1000次方
**Math.pow(10,1000) => Infinity**
加減乘除4個除了加法運算子與物件一起運算會得到字串,
其餘會嘗試將物件轉型失敗而得到NaN
* 「%」餘數運算子
* **731 % 360 => 11**
* Infinity
被除數是Infinity或-Infinity的情況下,取餘數後結果都是NaN
* **Infinity % 0 => NaN**
* **Infinity % 100 => NaN**
* **Infinity % Infinity => NaN**
* **Infinity % -Infinity => NaN**
* **100 % Infinity => 100**
* **0 % Infinity => 0**
#### 比較運算子(Comparison Operators)
### 「==」與「===」相等運算子
* 一般的相等運算子,在處理兩邊不同型別的情況時,
都會對他們進行一連串的強制轉型,又稱寬鬆的相等運算子
* **false == ""; --> true**
* **undefined == null; --> true**
* **"" == "0"; --> false**
* **false == []; --> true**
* **false ==![]; --> true**
### 嚴格的相等運算子
* 先比較運算子兩側值的型別,型別一樣的前提,才會往下比較是否為同一數值,
一但兩邊數值型別不一樣,就直接回傳false,
也有人會直接把這個嚴謹的運算子簡稱為全等於
* **false === ""; --> false**
* **undefined === null; --> false**
* **"0" === 0; --> false**
* **{} === {} --> false**
* **[] === [] --> false**
* 前面介紹的字串、數值、布林值、undefined跟null都概括的被稱為「純值」,
這個值單純是一個值,數值1永遠都只會是1,物件則是特別的型別
* 當物件被創造後,賦值給變數,變數所儲存的內容不是整個物件內容,
而是該物件存放的記憶體位置,也就是說整個物件再創造後會被分配到另外一個特定記憶體空間,然後變數拿到的只是物件的位置,而不是整個物件的數值內容
* 所以當物件被用於相等運算子的比較時,所比較的並不是物件內容,
而是物件存放的記憶體位置
* **var a = {};
var b = a;
a === b; => true**
* ===在某個新物件創造完之後,該物件記憶體位置會存放在變數a內,而後我再將存放這個物件記憶體位置的變數a內容指派給變數b,所以最後a與b的內容當然會是同一個記憶體位置,因此會得到true的結果
### 「!=」與「!==」反向的相等運算子
* ! = 的用法與 == 的用法一樣都會觸發自動轉型
! = = 不會自動轉型
因此實作上一樣推薦使用全等於 === 反向運算子! ==
* 「! =」returns true if the operands are not equal
* 「! ==」returns true if the operands are of the same type but not equal, or are of different type
### 「>」、「<」、「>=」、「<=」運算子
* **5 > 3; => true**
* **5 >=3; => true**
* **3 <=5; => true**
* 兩側如果不是純值,盡可能先將型別轉為數值型別
* 兩側都是字串.按照字串內字元的編碼值(Unicode)進行比較
* 如果一側為數值型別,一側為字串,則將字串嘗試轉為數值型別
* 布林值、null、undefined會被轉為數值型別,布林值false轉型後 會得到0,而true會得到1,null則會得到0
* undefined轉型後會得到NaN的結果,根據文件規範,NaN與任何數值 做比較都會得到false
* **undefined > 12; => false**
* **12 > undefined; => false**
* **12 > null; => true**
* **true > 0;**
### 「&&」AND運算子
* 狀況A與狀況B都必須成立才符合條件,AND運算子會從左邊的值開始判斷,當左邊的數值內容是布林值的false或可以被轉為false,就會回傳左邊數值的內容,只有當兩邊數值都是true,才會得到true的結果
* **false && true => false**
### 「||」OR運算子
* 狀況A或狀況B任一成立都符合條件,它一樣會先從左邊的數值開始判斷,只要運算子左邊數值是true或是可以被轉型為true,否則就會直接回傳運算子右邊的值
* **true|| false => true**
### 「!」NOT運算子
* 當NOT運算子右邊的數值為true或能夠被轉型為true,就回傳true,就回傳false,否則回傳true
* **!true => false**