## 會議記錄 導讀:奕洲 時間: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**