https://michaelnthiessen.com/force-re-render/
vue3 component reactive 用:key
component裡面不用加,加在父層就可以了
https://michaelnthiessen.com/force-re-render/
vue3 component reactive 用:key
component裡面不用加,加在父層就可以了
告訴我下面這段程式在做什麼? const list =txList.value.reduce((acc, item)=>{ if(!acc[item.txTerm])){ acc[item.txTerm] = [] } acc[item.txTerm].push(item) return acc },{}) ||[]; return list })
這段程式碼的主要功能是將 txList.value
中的項目根據 txTerm
屬性進行分組。以下是程式碼的逐步解析:
txList.value.reduce(...)
: 使用 reduce
方法來遍歷 txList.value
陣列,並將每個項目依據其 txTerm
屬性進行分組。
(acc, item) => {...}
: 這是一個回調函數,acc
是累積器,用來保存分組結果,item
是當前正在處理的項目。
if(!acc[item.txTerm])
: 檢查累積器 acc
中是否已經存在以 item.txTerm
為鍵的屬性。如果不存在,就創建一個空陣列。
acc[item.txTerm].push(item)
: 將當前項目 item
添加到相應的 txTerm
鍵的陣列中。
return acc
: 返回累積器,繼續下一個項目的處理。
{},
: reduce
的初始值設為一個空物件 {}
。
|| []
: 如果 reduce
的結果為假值(例如 undefined
),則返回一個空陣列。
最後,這段程式碼的結果是將 txList.value
中的項目分組後返回的物件,其中每個 txTerm
對應一個項目陣列。
當然可以!假設 txList.value
的內容如下:
javascriptconst txList = {
value: [
{ id: 1, txTerm: 'A', amount: 100 },
{ id: 2, txTerm: 'B', amount: 200 },
{ id: 3, txTerm: 'A', amount: 150 },
{ id: 4, txTerm: 'C', amount: 300 },
{ id: 5, txTerm: 'B', amount: 250 },
]
};
運行你提供的程式碼後,list
的結果將會是:
javascript{
A: [
{ id: 1, txTerm: 'A', amount: 100 },
{ id: 3, txTerm: 'A', amount: 150 }
],
B: [
{ id: 2, txTerm: 'B', amount: 200 },
{ id: 5, txTerm: 'B', amount: 250 }
],
C: [
{ id: 4, txTerm: 'C', amount: 300 }
]
}
在這個結果中,每個 txTerm
(A、B、C)對應一個包含相關項目的陣列。這樣就成功地將項目按 txTerm
分組了!
我們不能夠對 unknown
型別的東西進行任何除了讀寫和比較以外的操作
功能一:保證變數的值不會被不小心地操作到
例子:
function compareArrayAtEven(arr1: unknown[], arr2: unknown[]): boolean {
let diff = arr1.length - arr2.length;
if(diff > 1 || diff < -1) return false;
for(let i = 0; i < arr1.length && i < arr2.length; i++) {
if(arr1[i] !== arr2[i] + 2) return false; // TypeScript 會在這邊報錯
}
return true;
}
功能二:負責把關來自外界的輸入
預防各種執行階段中的不可預期現象發生
例子:
export function splitString(arg: unknown): string[] {
if(typeof arg == 'string') {
// 檢查完了之後才做我們真正要做的事情,例如:
return arg.split(',');
// 此處 TypeScript 會正確地知道 arg 的型別為字串,
// 因為剛才我們用 typeof 檢查過了。
// 對於更複雜的型別檢查,可以用 instanceof 關鍵字、
// 或是使用 TypeScript 的 TypeGuard 來達成,
// 這是題外話,這邊先不深入討論。
} else {
// 否則看要怎麼進行錯誤處理;這邊的方法是傳回預設值
return [];
// 或者也可以丟出一個 Error 包含了我們自訂的錯誤訊息
}
}
養成把對外 API 的參數宣告成 unknown
的好習慣,並且避免使用 TypeScript 中的 as
關鍵字來作型別斷言(取而代之地,應該使用 instanceof
或自訂的 TypeGuard 來確認型別)
any 隨便做都行,沒鑑別度
很大的程度上來說,是的;我個人現在是「TypeScript 程式碼中應該要幾乎沒有 any
才對」主張的擁護者。對於很多我接手的程式碼,我都會先搜尋出所有使用到 any
的地方,而它們大多都可以直接換成 unknown
而不用作額外的修改——而如果換成 unknown
之後某個地方因此就出現了編譯錯誤,那幾乎在所有的情況中,那都是突顯出了程式碼具有潛在的異味(bad smell),而釐清為什麼改成 unknown
之後有編譯錯誤、往往能讓程式碼變得更加健全。
只有一種情況是我會勉強接受 any
的使用的,那就是當我們引入了一個第三方的型別,我們很清楚其規格、但是我們偏偏又沒有該型別的完整定義檔、而我們自己去寫定義檔又很浪費時間的時候。然而,這樣的使用有幾個前提是應該要遵守的:
any
型別的物件應該要充分地被封裝起來,使得使用它的程式碼都非常清楚該變數要怎麼操作。如果有很多程式碼依賴於該物件,那應該要提供一個有良好定義型別的介面來讓其它程式碼間接操作該物件,而不是讓所有程式碼直接取用它。any
的狀態。如果沒辦法做到這兩點,那最好還是花一點時間自己把該型別當中會用到的東西宣告一下,這不僅能讓程式碼更有條理,也可以避免很多潛在的手殘可能性。
quiz:
const numbers = [33, 2, 8];
numbers.sort(); //[2, 33, 8]
Solution:
JavaScript is a dynamically typed language, which means that all standard library functionality must, at some point, decide how to work for most, if not all, use-cases.
Always keep in mind that the following array is valid:
const array = ["1", true, 55, 1.421, "foo", {}];
Array.prototype.sort
now needs to make a decision on how to handle such scenarios, and the solution is pretty straight-forward:
Convert all values to their string representation (because every value in JavaScript can always be converted to a string!), and then sort them in lexicographic order(字典順序).
Which basically makes sort see the array as this:
const intermediate = ["33", "2", "8"];
And in lexicographic order, no matter how many characters a string has, comparison starts at position 0, and "3"
comes before "8"
.
And in the end, the result is this:
["2", "33", "8"];
console.log(3 > 2 > 1); // false
因為
先比較 3>2 // true
後比較 true > 1
根據之前提及的 coercion變成Boolean(true) > 1 // false