[toc] # W_JS個人筆記 [三明治心得]() ### 閱讀方針 - 會很混亂 個人筆記 - 用現有知識拼湊出來得文章,會持續更新 - code範例 - 解釋細節 - 看不懂來跟我Argue - 0717 變更為術語筆記+邏輯筆記 ### 測試js - 首先需要先安裝node.js建立環境 - 在開啟專案的資料夾 - 開啟js - 開啟terminl`ctrl+~` - 輸入`node 當按名稱.js`,這樣就可以測試囉 ## this this,指向呼叫他的物件,這句話我咀嚼了很久,由於 Angular 有使用大量 this,所以我又去回顧了。基本上 this 是指向某個物件 ```javascript //part1 let hello = (){ console.log(this) } hello() //呼叫完會有以下 //非嚴格,一般環境下是指向 window; //非嚴格,node 是 global; //嚴格則是 undefinend //part2 class Hello{ setName(name){ console.log(this.name) } getName(){ console.log(this.name) } } const helloInCn = new Hello() helloInCn.setName("你好") helloInCn.getName()//你好 //這裡的 this 就是指向 helloInCn ``` # 術語筆記 # firstClass function 「第一級公民」指的是你可以將函式存放在變數、物件以及陣列之中,同時,你也可以將函式傳遞到函式,或者由另一個函式來回傳它。 而且,函式具有屬性,因為它實際上是一個「物件」。 ## key 作爲變數拿來取直 ```javascript= cosnt obj = { zh_tw: "yahoo.com.tw", en:"google.com" } const obj = { zh_tw: "yahoo.com.tw", en:"google.com" } let lang = "en" console.log(obj[lang])//google.com ``` ## 集合資料結構的分類 這些結構可以根據功能進一步分類: 鍵值對資料結構(Key-Value Pairs) - Object - Map - WeakMap 集合型資料結構(Value Collections) - Set - WeakSet # 淺拷貝vs深拷貝 ```javascript= // 原始陣列 const originalArray = [ { name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }, { name: 'Charlie', age: 35 } ]; // 使用 Array.prototype.slice() 進行淺拷貝 const newarr = [...originalArray] // 修改淺拷貝中的元素 originalArray[0].age = 26; // 打印原始陣列和淺拷貝 console.log('Original Array:', originalArray); console.log('newarr Copy:', newarrCopy); //淺拷貝對原先得originalArray修改會影響到newarr /*[ { "name": "Alice", "age": 26 }, { "name": "Bob", "age": 30 }, { "name": "Charlie", "age": 35 }, ]*/ originalArray[3] = {name: "watson", age:30} console.log('Original Array:', originalArray); console.log('newarr Copy:', newarrCopy); //淺拷貝對originalArray新增一筆資料不會影響到newarr /*[ { "name": "Alice", "age": 26 }, { "name": "Bob", "age": 30 }, { "name": "Charlie", "age": 35 }, { "name": "watson", "age": 30 } ]*/ ``` ## 對象字面量 目前理解為"object literal" ,指的是用大括號 {} 直接創建和初始化物件的語法形式。 ## 科理化 定義:簡單來說就是執行參數的方法,但是參數不是一次處理完,而是一層一層的往下走,透過函式先執行第一個,往裡面之後,在透過另一個函式執行下一個參數,直到執行完畢 首先要函式裡面在包一次函式;隨後先給一半參數,另外一半之後在給它並且執行 ```javascript= // 柯里化的加法函數 function curriedAdd(x) { return function(y) { return x + y; }; } console.log(curriedAdd(2)(3)); // 5,這裡兩個()代表呼叫兩個函式 ``` ## 運算子 一元正號運算子 會轉換型別 | 操作數型別 | 轉換結果| |--------|--------| | number | 保持不變。 | |string |嘗試將字串解析為數值。如果字串無法解析,則結果為 NaN。| |boolean |true → 1,false → 0。| |null|轉換為 0。| |undefined |轉換為 NaN。| |object 或 array |先嘗試調用 valueOf(),若無法轉換,再調用 toString(),最終結果轉換為數值或 NaN。| ```javascript= console.log(+{}); // NaN (物件無法轉為數值) console.log(+[]); // 0 (空陣列轉為空字串,空字串再轉為 0) console.log(+["123"]); // 123 (陣列中只有一個元素,該元素為數值型字串) console.log(+["123abc"]); // NaN console.log(+[1, 2, 3]); // NaN (多個元素的陣列無法直接轉為數值) ``` ## 閉包closure 白話就是說內部函式可以摳得到外部得變數,並且除存使用 ## pure function 指一個function是否依賴外部變數 如果不會就是pure,會就是非pure 拈花惹草就不pure,可以先這樣理解,但沒有好壞 ```javascript= // 非純函數:輸出取決於外部狀態,且有副作用 let count = 0; function increment() { count += 1;// 修改外部狀態 return count; } console.log(increment()); // 1 console.log(increment()); // 2(輸出取決於外部變量 count 的值) ``` ## partial application 不一次給全部參數,而是一次只給一部分參數得到新的function使用方法 ## callback CallBack又稱為回調、回函、回呼函式,光是這個翻譯就看不懂了,在這邊我將CallBack的定義解釋為:在某一函式執行時或執行後,依條件或依序去執行所傳遞進來的函式。 ### 簡單的來說,就是 一個程式執行完再去執行另一個程式 1、讓函式成為另一個函式的參數 2、讓函式控制參數函式的執行時機 ```javascript= function A(FnB, FnC) { setTimeout(function(){ console.log('this is a function'); FnB(FnC); },0); } function B(Fn) { console.log('this is B function'); Fn(); } function C() { console.log('Run Finish'); } A(B,C) //回傳 this is a function this is B function Run Finish ``` ## Ajax 可以向伺服器傳送及取得資料,並且不需要重新整理瀏覽器畫面,這樣可以大幅提升使用者體驗並且減少伺服器負擔 ## 迴圈 ## for ### continue vs break cotinue - continue 關鍵字用於跳過當前迴圈的剩餘程式碼,直接進入下一個迴圈迭代。 - 當需要跳過某些條件下的迴圈邏輯,但不結束整個迴圈。 - 在不符合某些條件時,立即進入下一輪迴圈。 break - break 關鍵字用於立即終止迴圈的執行,不再執行迴圈中剩餘的程式碼,並跳出迴圈。 - 當迴圈條件外的某個條件達成時需要提前結束迴圈。 - 用於避免無限迴圈或在特定條件下停止迴圈的執行。 # undefined 已宣告變數未定義就會跳undefined # NaN 型別沒有成功轉型為數值 無法計算就會跳出NaN # null 有意而為之 想讓變數是空值 ```javascript= let nothing = null; ``` 如果用`typeof`檢查會發現跳出object 這是null成年舊bug 已不可動搖 # 建構式 constructor 也是function 差別 - 函式名稱開頭要大寫,為了容易變別 - 不能用 return 指定要回傳其他內容,如果加上 return,就只會回傳指定內容,而不會回傳一個新物件。 ```javascript= // 定義一個建構函數(Constructor) function Car(brand, model, year) { this.brand = brand; this.model = model; this.year = year; } // 使用建構函數創建物件實例 let myCar = new Car('Toyota', 'Corolla', 2020); // 輸出實例的屬性 console.log(myCar.brand); // Toyota console.log(myCar.model); // Corolla console.log(myCar.year); // 2020 //另一種方式 // 定義一個類(Class) class Car { constructor(brand, model, year) { this.brand = brand; this.model = model; this.year = year; } // 定義一個方法 displayInfo() { console.log(`Brand: ${this.brand}, Model: ${this.model}, Year: ${this.year}`); } } // 使用類創建物件實例 let myCar = new Car('Toyota', 'Corolla', 2020); // 呼叫實例的方法 myCar.displayInfo(); // Brand: Toyota, Model: Corolla, Year: 2020 ``` # 樣板字面值 它產生出來得會是字串,如果想要數字可運算那就寫在一起 ${num+num} like this - 插值表達式 使用${}語法將變量或表達式嵌入到字符串中: - 多行字符串 樣板字面值可以直接換行,不需要使用轉義字符: - 嵌入表達式 可以在樣板字面值中嵌入任意的JavaScript表達式: - 嵌套樣板字面值 你可以在樣板字面值中嵌套樣板字面值: - 樣板字面值中的函數調用 可以在樣板字面值中調用函數: - 樣板字面值中的條件式 可以使用條件表達式來動態構建字符串: - 樣板字面值中的數組或對象 你也可以使用樣板字面值來處理數組或對象: #### 其他搞法 可以使用 funtion 當模板字串 ```javascript= function A(){ console.log() return } A`xxx`//一種呼叫方式 不是()而是`` ``` --- # 已加強理解或使用過 ### *對preseInt()的理解 - 可以將字串轉換回數字 - 整數 ### *對Number()得理解 - 強制得將字串轉為數字 --- # i++ vs ++i call by value ++i:i 的值會增加 1,並且立即返回更新後的值。 一句話總結:先更新,後返回新值。 ```javascript= i=1 j=i++ //i=2,j=2 ``` i++:i 本身的值確實會增加,但返回的值是增加前的原本值。 用一句話說就是:返回舊值,更新新值。 ```javascript= i=1 j=i++ //i=2,j=1 ``` # type module vs commonJS 這是js模組,會引想一些語法,比方我遇到得給使用者輸入值得部份 # 語法糖 >指電腦語言中添加的某種語法,這種語法對語言的功能沒有影響,但是更方便程式設計師使用。語法糖讓程式更加簡潔,有更高的可讀性。 語法鹽(英語:syntactic salt) : 指的是不容易寫出壞代碼的語法特性。這些特性強迫程式設計師做出一些基本不用於描述程式行為,而是用來證明他們知道自己在做什麼的額外舉動。 語法糖精(英語:syntactic saccharine) : 或者說語法糖漿(英語:syntactic syrup),指的是未能讓編程更加方便的附加語法。 # Node.js # 解構賦值(destructuring assignment) 間單來說就是把右邊想同數量得值傳給左邊相等數量得值 # 正正提到得概念 ex. main() 只要看到這個 不管是否有參數 都是一種呼叫方式 ## 三元運算子ternary # 箭頭函式 - 不會有作用域隔閡 - 省去function,用=>取代 - 箭头函数在只有一条语句时可以省略大括号 {}, - 多条语句或需要显式返回值时,通常需要使用大括号 {}。 ```javascript= const function1 = x => x+1 會有回傳值 const function1 = x => {x+1} 要家return才有回傳值 ``` --- # throw & return 兩者都能中斷程式碼執行,那是不是用哪個都沒差呢? 先說 return ,只能在 function 中使用,用來回傳值並中斷 function 執行。 回傳值。 ```javascript= function test(){ return 123; xxxxxx // 這邊不會執行 } test(); //123 ``` 如果沒寫會回傳 undefined。 ```javascript= function test(){ return; xxxx //這邊不會執行 } test(); // undefined ``` 再來是 throw,任何地方都能用,用來拋出例外並中斷程式碼執行。在瀏覽器會用紅色來呈現例外。 ```javascript= throw 123; // Uncaught 123 ``` 不能單獨使用,一定要丟出東西,不然會出錯。 ```javascript= throw; // Uncaught SyntaxError: Unexpected token ';' ``` 最後來整理一下: 兩者都能中斷程式碼。 return 只能在 function 中使用, throw 沒限制。 return 後面可以不用寫值, throw 後面一定要有值。 --- # 相依性 - 在計算時執行方像,如果是從左往右,就是左相依性,反之就是右相依性 - 左相依性:true || false - 右相依性:var a = 100 # 物件理解 - cerly breckt - `key:value` - 一個資料結構可以存放所有資訊 # 陣列 - 中括號 # export & import # function() - 函式 - 可重複利用的程式碼塊 - 避免撰寫重複的程式碼 - 如果return在裡面,就會以return為標準 --- # object - 物件也是變數 - 物件與物件之間不能比較(本身例外),即便內容一致,會得出false,若是用函式定義物件想等,那這樣就會是true - 物件可以除存多個值,複合型別 - 物件與變數的不同在於,變數通常用來存儲單個值,而物件則可以存儲多個值 ### Object.value 這是一個靜態方法,因為 ### Object.define系列 > 保護你的物件,位物件設立開關 > ```javascript= const obj = {}; // 先建立空物件 Object.defineProperties(obj, { name: { value: 'John', writable: true, enumerable: true, configurable: true }, age: { value: 30, writable: false, // 不可改變 enumerable: true, // 可列舉 configurable: false // 不可刪除或重新定義 }, greet: { value: function() { return `Hello, my name is ${this.name}`; }, enumerable: false, // 不列舉 writable: false, // 無法改寫 configurable: true } }); console.log(obj.name); // "John" console.log(obj.age); // 30 console.log(obj.greet()); // "Hello, my name is John" // 修改 writable: true 的屬性 obj.name = 'Jane'; console.log(obj.name); // "Jane" // 嘗試修改 writable: false 的屬性(無效) obj.age = 25; console.log(obj.age); // 30 // 列舉屬性 console.log(Object.keys(obj)); // ["name", "age"],"greet" 被排除 ``` #### Object.defineProperties() 與 Object.defineProperty() 的區別 |特性|Object.defineProperty()|Object.defineProperties()| | :-- | --: |:--:| |定義屬性數量|一次只定義一個屬性|一次定義多個屬性| |是否細化屬性行為|可以細化(writable, enumerable 等)|可以細化每個屬性行為| |調用複雜度|適合單一屬性操作|適合大量屬性設置| --- # 運算子 ![Screenshot from 2024-05-13 09-58-14](https://hackmd.io/_uploads/rkiTmlJ7R.png) - 優先性與相依性 ![image](https://hackmd.io/_uploads/B1TLimCWC.png) - =符號在js裡面叫做指派運算子,意旨把右邊的值指派給左邊 boolen+number=值 boolean+boolean=0 ### 邏輯運算 - || = or - 基本上第一個值是true就會回傳true&第一個值,EX: - 3||10 回傳 3 - false||10 回傳 10 - 0||10 回傳 10 0=false - 只要有一個參數是true就會回傳true - && = and - 在&&後面得值會決定一切,除非前面是false - 3 && 10 在都是true情況下回傳10 - false && 10 回傳false 因為前面是false後面就免談,此現象也稱為短路性質 - 同上提 0 && 20 造上面邏輯,會是回傳0,0=false - 嚴格判斷,只要一方式false就是false - ! = not 感覺很像相反 --- # Variables ### var - 變數 - 1995-2015 主流用於舊網站 ### let - 變數 - 2015加入 - 如果不能使用const就用let ### const - 常數 - 2015加入 - 嚴格規定,數值不可以更改情況下可以使用 ### 字串 如果第一位為" "字串,那整串都會變字串 - `let x = "5" + 2 + 3` 求出523 如果最後一位變成字串,那前面會相加在變字串 - `let x = 2 + 3 + "5"` 求出55 --- # String ## 基本認知 - 只要有""或''都是字串 - 字串,如果是求字符位置,第一位數為[0] - EX:'hello',h得位置是在第0位,e則是第1位,以此類推 - 字串,如果是求字符長度,第一位數為[1] - EX:'hello',有五個字,所以長度是5 ## String Methods ### lenght - length自動計算字串得總數量,下方得出26 ``` <p id="demo"></p> <script> let text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; document.getElementById("demo").innerHTML = text.length; </script> ``` ### chatAt() - 得出字串指定索引得位置,會得出H ``` <script> var text = "HELLO WORLD"; document.getElementById("demo").innerHTML = text.charAt(0); </script> ``` ### charCodeAt() - 回傳指定索引得unicode,會得出72,H在unicode是72 ``` <script> let text = "HELLO WORLD"; document.getElementById("demo").innerHTML = text.charCodeAt(0); </script> ``` ### at() - 跟chatAt()很像,唯一不同是at可以用負值,會得出D ``` <script> var text = "HELLO WORLD"; document.getElementById("demo").innerHTML = text.charAt(-1); </script> ``` ### slice() - 切分,選取兩個參數作為起始點與結束點,會的出Banana ``` <script> let text = "Apple, Banana, Kiwi"; let part = text.slice(7,18); document.getElementById("demo").innerHTML = part; </script> ``` - 如果指填7,那就會從第7位之後往前推,得到"Banana, Kiwi" - 如果填-12,答案也會是"Banana, Kiwi",等於事先從尾段先到回來,在往前 - 如果是-12,-6,答案會是"Banana" - 其他項相似,先知道就好 - substring() - substr() ### trim() - 會消除字串兩側空白,並算出長度,trim會得出text1為12 ``` <script> let text1 = " Hello World! "; let text2 = text1.trim(); document.getElementById("demo").innerHTML = "Length text1 = " + text1.length + "<br>Length text2 = " + text2.length; </script> ``` - 其他項相似,先知道就好 - trimStart() - trimEnd() ## String Search ### indexOf() - 回傳字串位置,會得出7 ``` let text = "Please locate where 'locate' occurs!"; let index = text.indexOf("locate"); document.getElementById("demo").innerHTML = index; ``` ### lastIndexOf() - 會回傳出文字在字串中最後一次出現得位置,會得出21 ``` let text = "Please locate where 'locate' occurs!"; let index = text.lastIndexOf("locate"); document.getElementById("demo").innerHTML = index; ``` - 以上兩個如果在字串中找不到相應得值,就會回傳-1 - 都可以在輸入第二參數來作為索引起始點`let index = text.indexOf("locate",15);` ### search() - 會回傳在字串中,第一次出現得位置,會得出7 ``` let text = "Please locate where 'locate' occurs!"; let index = text.search(locate); document.getElementById("demo").innerHTML = index; ``` ### matchAll() - 在字串中搜尋指定的文字,會回傳所有相關文字,會得到Cats,Cats - 如果加上`(/Cats/gi)`會全選 ```javascript= <script> let text = "I love cats. Cats are very easy to love. Cats are very popular." const iterator = text.matchAll("Cats"); document.getElementById("demo").innerHTML = Array.from(iterator); </script> ``` --- # number - 如果字串後面接著數字,那數字會背編譯程字串,數字相加無效 - 數字雖然+無效,但是可以- * /,比方"10"*"10"="100" --- # Array.prototype - 索引起始為[0],所以[0]是第一位元素,[1]是第二元素 ### sort 可以理解為陣列排序工具 - 純粹使用就是將陣列得內容轉為字串,並且擷取unicode比較大小來排序 - 如果有加入比較,就是用大小排序 比方a-b 就會是小到大 b-a反之f ## Array method ## Array Iteration ### reduce() - 將陣列的所有值轉換為單一值 - 運作原理是由左到右 - reduce()不會刪減陣列得數值 ```javascript= <!-- 所有數值 --> const numbers = [45, 4, 9, 16, 25]; let sum = numbers.reduce(myFunction); <!-- myFunction()裡面可以自訂值得名稱,最多不超過四個參數 --> function myFunction(total, value, index, array) { return total + value; } retuen = 99 //total:目前的累加總和。 //value:目前正在處理的元素值。 //index:目前正在處理的元素索引。 //array:原始的陣列。 ``` - total是計算機,當沒有任何相加得情況下回船會是第一個數值,也就是45 - value是迭代,它會在數值中跑,跑到最後一位就停了,照上面最後一位也就是25 - index代表值得==數量==,如上方number,總共有五位,但是計算方式是第一位為0,第二位是1,以此類推,所以會得出4。如果是在相加時,它計算方式就會變成0+1+2+3+4(依照值得數量,以此類推) - array代表得是顯示數值,回傳會是45, 4, 9, 16, 25 所以根據上面`return total + value; `就可以得知算式=45+4+16+25=99 如果是`return total + index; `就會是=45+0+1+2+3+4=55 如果是`return value + index; `它就會使用迭代,過程中參數都會相加,但是只會取最後相加得值=45+0=45,4+1=5,9+2=11,16+3=19,25+4=29所以可以得知最終回傳是29 --- # if else & ? ? 直接判斷 true false ,不能寫throw Error --- # this Keyword --- # bigint - js整數最多只能到15位,所以這是用來解決超過15位得問題 - 可以寫`bigint(9999999999999999)`,也可以在數字後面加上n=`9999999999999999n` - 不能有小數 ### Safe Integers - 安全整数是指 JavaScript 中可以精确表示的整数范围。 - 安全整数的范围是从 -(2^53 - 1) 到 (2^53 - 1)。 - 这个范围足够大,可以满足大多数实际应用的需求。 - 安全整数范围是从-9007199254740991到9007199254740991。 ```javascript= MAX_SAFE_INTEGER //最大 MIN_SAFE_INTEGER //最小 ``` # Number ## Number Methods - 判斷使否為整數 ```javascript= Number.isInteger() //判斷是否為整數 Number.isSafeInteger() //判斷是否在安全整數範圍 ``` ### toString() - 教數字轉換為字串 ### toExponential() - 顯示小數點以後得數字 ### toFixed() - 四捨五入到指定得數,適合作為金錢運算使用 ### toPrecision() - 從最左邊開始數 ### Number() - 轉換數字字串為數值 - 不允許有空格 - 轉換`Number(new Date("1970-01-01"))`,以1970-01-01基準點=0,加一天就是[24*60*60*1000毫秒]=86400000 ### parseInt() - 捨去小數點 - 將字串轉換為數字 - 允許有空格 ### parseFloat() - 將字串轉換為數字 - 允許有空格 ### 其他相關 - Number.parseFloat() ## Number Properties --- # typeof() - 使用它會回傳字串,用來表示超做數值類型 ```javascript= console.log(typeof 42); // Expected output: "number" console.log(typeof 'blubber'); // Expected output: "string" console.log(typeof true); // Expected output: "boolean" console.log(typeof undeclaredVariable); // Expected output: "undefined" ``` --- ### json 如果要轉換js格式為json,就要用json.stringify json.parse = 將字串轉換為js物件 json.stringify = 將一個JavaScript 物件或值轉換為JSON 字串 Json.stringify這裡J大寫得原因,是因為這是一個建構子,就類似Object.value --- ### fetch 如果只有`fetch("https://jsonplaceholder.typicode.com/users")`那就是預設GET ## Expressions & operators ### instanceof 這是用來檢查原型鍊源頭 ```javascript= function Car(make, model, year) { this.make = make; this.model = model; this.year = year; } const auto = new Car('Honda', 'Accord', 1998); console.log(auto instanceof Car); // Expected output: true console.log(auto instanceof Object); // Expected output: true ``` # Event ## 冒泡事件 stopPropergation:阻止冒泡事件得其中一個方法 preventDefault:阻止冒泡事件得其中一個方法 # 累積表達式(cumulative expression) ## console.error vs throw new Error ### console.error - 功能:記錄錯誤訊息到控制台。 - 影響:程式繼續執行。 - 使用情境:非致命錯誤、日誌記錄或除錯用。 ### throw new Error - 功能:拋出錯誤並中斷程式執行。 - 影響:需要用 try...catch 捕獲,否則程式會崩潰。 - 使用情境:致命錯誤,需要立即處理或通知呼叫方。 ## Vue表單的課 >Chris: >看到表單,第一個要先想象他是物件,處理標資料形態,甚至要想象它是什麼型別,,這object是什麼欄位,而欄位是什麼型別 getter setter 活用版本 原生只會處理畫面,要清除資料要另外 ## 頁面刷新技術 Router SPA AJAX AXIOS Router 都有異曲同工之妙,主軸是用於在使用者切換頁面時,不刷新整個頁面的情況下更新顯示的內容。它的主要目的是提供更順暢的用戶體驗,並模擬傳統網站的頁面導航行為。