# Javascript程式語言 > 2020-08-16 上課筆記 ## 基本資料型態 ### 常數 ![](https://i.imgur.com/HR1VBJe.png) ``` const i = 1.02e2 // 1.02 * 10^2 ``` ### 基本資料型態與分類(兩者差異在於「變數值存入變數的方式」) | 分類 | 資料型別 | 說明 | | -------- | -------- | -------- | | 基本型 | number | 數值 | | 基本型 | string | 字串 | | 基本型 | boolean | 布林 | | 基本型 | symbol | 符號 | | 基本型 | null/undefined | 空/未定義 | | 參考型 | array | 陣列(資料集合-可透過索引值存取標籤) | | 參考型 | object | 物件(資料集合-可透過名稱存取標籤) | | 參考型 | function | 函式(函數)-一連串處理(步驟)的集合 | ## 基本型 基本型態的變數可直接填入變數值 ## 參考型 參考型態的變數則用以儲存參考值(用以儲存「值」的記憶體位置)。 ### 陣列 ``` n = [1, 2, 3] n = ['a', 'b', 'c'] n = [1, 'a', 2, 'b'] console.log(n) console.log(n[2]) ``` ### 物件 ``` n = {a: 1, b: 2, c: 3, 123:5} console.log('物件', n['b']) console.log('物件', n['123']) ``` ### 小數 ``` f = 0.7 f *= 10 console.log((1*10 - f)/10) ``` > 注意: > - Javascript是用二進制來計算數值,之後再轉換成十進制,因此會有誤差。 > - 引用Math或BigDecimal.js等等可以解決浮點數運算的問題。 ### 變數定義 #### let與var的不同 ![](https://i.imgur.com/HR1VBJe.png) - let無法重複定義,但var可以。 - let指令能更詳細的控制變數的有效範圍。 ### 樣板字串-嵌入變數 ![](https://i.imgur.com/HR1VBJe.png) 格式:**${變數名稱}** ``` var age = 7 var des = `我今年${age}歲` ``` ### 多行字串 ![](https://i.imgur.com/HR1VBJe.png) ``` let test = `今天天氣熱 明天天氣好` console.log(test) ``` ## 運算子 ### 指派運算子 ``` a = 5 console.log(a += 5) // a = a + 5 console.log(a -= 2) // a = a - 2 (a=10 -> a=8) console.log(a *= 3) // a = a * 3 (a=8 -> a=24) console.log(a /= 4) // a = a / 4 (a=24 -> a=6) console.log(a %= 5) //a = a % 5 (a=6 -> a=1) ``` ### 基本型態與參考型態經過指派後的差別 1. 基本型態會複製本值,因此指派後的修改不影響原來變數內容。 2. 參考型態為複製參考,因此指派後的修改會影響原來變數內容。 ``` a = 'str'; console.log('基本型指派前:', a); a1 = a; a1 = 'rts'; console.log('基本型指派後:', a); b = [1, 2, 'v']; console.log('參考型指派後:', b); b1 = b; b1[2] = 99; console.log('參考型指派後:', b); ``` 結果: ``` 基本型指派前: str 基本型指派後: str 參考型指派後: [ 1, 2, 'v' ] 參考型指派後: [ 1, 2, 99 ] ``` ### 解構指派 ![](https://i.imgur.com/HR1VBJe.png) #### 陣列解構指派 例如將一個陣列元素分別指定給不同的變數,原本用法: ``` c = [1, 2, 3, 4, 5]; c1=c[0] c2=c[1] c3=c[2] c4=c[3] c5=c[4] ``` 解構指派用法: ``` c = [1, 2, 3, 4, 5]; [c1, c2, c3, c4, c5] = c; ``` > 注意:要用中括號包住 更多範例: ``` d = [1, 2, 3, 4, 5]; let [d1, d2, d3, d4, d5] = d; console.log(d1, d2, d3, d4, d5); ``` #### 透過「...」將放不下的元素以陣列方式指定 ``` e = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; let [e1, e2, e3, e4, e5, ...other] = e; console.log(e1, e2, e3, e4, e5, other); ``` #### 變數交換 ``` c = 5; d = 9; // [temp = c // c = d // d = temp [c, d] = [d, c]; console.log(c, d); ``` #### 物件解構指派 ``` let aa, bb, cc; let o1, o2, o3; array1 = [1, 2, 3]; obj1 = {a:1, b:2, c:3}; [aa, bb, cc] = array1; console.log(aa, bb, cc); ({o1, o2, o3} = obj1); //物件指派寫法 console.log(o1, o2, o3); ``` > 變數名稱必須與屬性名稱相同 #### 巢狀物件解構指派 ``` c = { x: 1, y: 2, z: 3, child: { x1: 4, y1: 5, z1: 6 } }; let {x, y, z, child: {x1, y1, z1}} = c; console.log(x, y, z, x1, y1, z1) ``` #### 設定別名 ``` // 設定別名 c = { a: 1, b: 2, c: 3 } let {a:name, b:title, c:content} = c; console.log('name=', name, 'title=', title, 'content=', content); array1 = [1, 2, 3]; obj1 = {a:1, b:2, c:3}; let aa, bb, cc; let o1, o2, o3; [aa, bb, cc] = array1; console.log(aa, bb, cc); ({a:o1, b:o2, c:o3} = obj1); //物件指派寫法 console.log(o1, o2, o3); ``` ### 比較運算子 ``` console.log(1 == '1'); console.log(1 === '1'); console.log(1 != '1'); console.log(1 !== '1'); a = 3; b = 5; if(a > b) { console.log('a比b大'); } else { console.log('a比b小'); } console.log('a比b' + (a > b ? '大':'小')); ``` ### 捷徑運算 下列值皆為false: - 空字串('') - 數值0、Nan(Not a Number) - null、undefine > 執行順序:由左到右做比較 ``` b = 0; c = 3; a = b && c; console.log(a); a = b || c; console.log(a); ``` 結果: ``` 0 3 ``` ``` a1 = 'a'; a2 = 99; a3 = false; a4 = [0, 0] a5 = {} console.log(a1 && a2 || a3 && a4 && a5) console.log(a2 && a5 || a4 && a5) console.log(a5 || a2 && a3 && a4 && a5) console.log(a4 || a2 || a3 || a5) ``` 輸出結果: ``` 99 {} {} [ 0, 0 ] ``` ##### 練習 1. a, b為兩個字串,如果相同就顯示「相同」否則顯示「不同」。 ### delete運算子 ``` a = 4; delete a; console.log('a=', a); // 這裡會出現例外錯誤,因為a變數被刪除了 // 明確宣告的變數無法刪除(let或var) var a9 = 9; delete a9; console.log('a9=', a9); // a9仍然存在 // 陣列索引刪除後,後面的會往前移,只是原來的元素存取時會出現undefined a = [1, 2, 3]; delete a[1]; console.log(a[1]); console.log(typeof a); // 刪除屬性,物件本身不會被刪除 a = {a:1, b:2}; delete a.b; console.log(a); ``` ### typeof運算子 ``` a = 9; console.log(typeof a); a = '9'; console.log(typeof a); a = false; console.log(typeof a); a = [1,2,3]; console.log(typeof a); a = 1.5; console.log(typeof a); ``` 輸出結果: ``` number string boolean number object ``` > 陣列跟物件都只回傳object ### 運算子優先順序 ``` a = 7 console.log((3 + 5) * 6); console.log(a); z = a += 9; console.log(z); z += 9 + 8 * 2; console.log(z); ``` > 如果無法確定運算子優先權,但想優先運算的話,可以使用小括號包圍,因為小括號優先權最高。 ## 控制語法 程式結構一般分為三類: 1. 依照撰寫順序執行的「循序」。 2. 依照條件分岐的處理「選擇」。 3. 重複執行特定處理的「重複」。 ### if ### switch ### for ### for...in ### for...of ![](https://i.imgur.com/HR1VBJe.png) ### bread/continue ### 一次跳出巢狀迴圈 - label ### 例外處理 - try...catch...finally ### 避免JavaScript錯誤與法 - Strict模式 ### 非同步載入外部程式 - async/defer屬性 ##### 將<script>標籤放在網頁最後面(例如: </body>前面) ``` 'use strict'; ``` | 分類 | 限制 | | -------- | -------- | | 變數 | 禁止省略var | | 變數 | 禁止使用未來保留的關鍵字 | | 變數 | 禁止參數、屬性名稱重複 | | 變數 | 禁止undefined/null指派 | | 指令 | 禁止使用with | | 指令 | 禁止存取arguments.callee | | 指令 | Eval指令宣告之變數 | | 其他 | 函數內的this無法轉成全域物件(會變成undefined) | | 其他 | 禁止「0-」的8進位常數值 | ##### 優點: 1. 避免JavaScript陷阱。 2. 執行速度比Strict快。 3. 可增加未來相容性。 4. 可更加了解JavaScript的禁止狀況。 ##### 使用HTML5非同步與法 ``` <script async src="app.js"></script> ``` > 以src屬性設定的程式會透過非同步方式載入,在載入結束之後才接著執行。 ``` <script async defer src="app.js"></script> ``` > 整個頁面都下載及分析完成後才會執行程式。 ## 函式 ##### 何謂函式: 1. 一段事先準備好的特定功能程式碼區塊。 ##### 函式功用: 1. 減少重複的程式碼。 2. 讓程式更簡潔更有架構。 3. 讓程式碼更容易閱讀。 ##### 函式結構: 1. 含式名稱。 2. 程式碼區塊。 3. 參數。 4. 回傳值。 命名規則: 1. 第一個字元只能是英文大小寫、底線、$號 2. 第2個字元及之後可以是英文大小寫、數字、底線、$號。 3. Javascriot保留字不可作為函式名稱。 4. 命名方式為snake命名法,全小寫,以底線分隔單字。