---
# System prepended metadata

title: 三明治2
tags: [讀書會]

---

## 會議記錄
導讀：奕洲
時間：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語法糖  把東西包裝好
  
  ![截圖 2025-05-05 上午11.53.11](https://hackmd.io/_uploads/Sy_DUhHglg.png)

 * 作用域(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**