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
console.log(typeof typeof 1); // string
This actually returns "string"
.
This expression is evaluated from right to left.
The first sub-expression evaluated actually is typeof 1
which will return "number"
.
Only after that the next sub-expression is evaluated which now is typeof "number"
which returns "string"
.
console.log("This is a string." instanceof String); // false
This actually returns false.
The reason for that circumstance is that JavaScript distinguishes between primitives and objects.
And "This is a string." is actually a primitive string and not an instance of the object String.
If the code was like this:
new String("This is a string.") instanceof String
you'd actually get the result you would have expected at the beginning.
What instanceof
actually does is checking if the String constructor is nested within the prototype chain of the value provided.
In this case, it isn't.
The plus operator is defined for numbers and strings and as soon as a string is present on either the left or right side, a string concatenation is perfomed.
// 1st step
'b' + 'a' -> 'ba'
// 2nd step
'ba' + + 'a' // wait a second!
'a'
to a number will actually yield NaN
!// 1st step
'b' + 'a' -> 'ba'
// 2nd step
'ba' + + 'a' -> 'ba' + NaN -> 'baNaN'
// 3rd step
'baNaN' + 'a' -> 'baNaNa'
// 4th step
'baNaNa'.toLowerCase() -> 'banana'
quiz:
// 1st step
false == '0'
// 2nd step
Number(false) == '0' -> 0 == '0'
// 3rd step
0 == '0' -> 0 == Number('0')
// 4th step
0 == 0 -> 0 === 0 -> true
solution:
there is a hierarchy for type coercion in JavaScript. The coercion process follows a set of rules:
null
or undefined
, they are considered equal (unless strict equality is being used with the "===" operator).valueOf()
or toString()
methods of the object.console.log(typeof NaN); // number
console.log(Number([])); // 0
console.log(Number(![])); // 0
console.log(Number([2])); // 2
console.log(Number([0,0])); // NaN
**
undefined means this thing has no value for some reason. Most of the times you encounter undefined it means that something has gone wrong.
On the other hand, null means this thing has no value, I recognise this and it's the way I would like it to be. 看見null表示是編寫者故意設的typeof(undefined) | Should output ← "undefined" |
typeof(null) | Should output ← "object" This is regarded by many as a mistake in the language. It's too late to fix it now so we'll have to deal with it. |
未看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw
https://zhuanlan.zhihu.com/p/675860025
1.过去改变不了,未来展望不到,现在凑合着过吧。
2.没有什么水逆 ,你只是在给自己的好运蓄力。
3.大家可以放肆的去热爱生活的同时,也更加热爱自己,当你热爱生活的时候,我觉得生活也会更加的热爱你,让每天都可以成为幕圆满的每一天。
4.没有人能够决定你的选择是对是错。
5.我很幸运,把自己的热爱变成了事业。
6.选择音乐从来不是一件勇敢的事,坚持才是。
7.我有自己的坚持,有自己的追求,也有自己想要的更多的东西,不是我贪心,只是我想获得更多的尝试。
8.一定要快乐,要幸福,做自己想做的,要自由。
9.我觉得自己现在就是一颗想燃烧,但是燃烧了一半就是半燃烧的一颗恒星!
10.未到结局,焉知生死,不到最后,你永远不知道自己能创造出什么机会和可能。
11.灯光老师麻烦把灯关一下谢谢,这个时候不需要有我们有她们就够了。
12.也许那是最后无悔与忠贞,才是成长的真谛吧。
13.难熬的时候终归是难熬的,过了这段时间会是一片彩虹。
14.我不怕熬夜,不怕失败,我可以重来。
15.什么时候不满意自己,那就打碎不满意的自己。
16.我希望每一个年轻人在寻找自己梦想的同时,都不要只停留在自己的想象里。
17.枯燥的过程机械的反复练习,才是你走进自己心之所向的唯一途径。
18.我摔倒了就爬起来,爬起来下次接着摔呗,下一次要更华丽的摔到。
19.年轻人正处在一个积极接触外界的一个阶段,被误解、否定、偏见在所难免。但是一个年轻人想要证明自己,想要获得认可,除了不被个人情绪打倒,更重要的是学习如何成为一个更好的大人。
20.我觉得做什么事儿都是要有野心的,要给自己定一个也许攀登都攀登不到的一个高度。如果你连给自己设立目标的勇气胆量都没有,我觉得真的是,搬砖吧。
21.其实有的时候如果你可以简单的伸出一只援手,在我们生活的这样的一个环境中,当我们真的感受到别人的爱的同时,我们也要自己主动的敞开心扉去爱身边的一个人,我觉得如果这样的话,可以让整个环境可以变得越来越暖。
22.现在回想起这段时光,其实我记得 其实不是辛苦其实我觉得更多的是对自己的感谢,因为选择了一条更难的路,并锻炼出了更结实的羽翼。
23.多经历一些坏事才是好事,开心的日子是短暂的,痛苦的日子是永恒的。
24.一条自由的鱼,想去哪就去哪,至少在我这个年龄,我有底气说这个话,我是自由的。
25.我们之中有的人会在外界的压力下变得畏首畏尾也看的人会因自我的迷茫而放弃自己热爱的方向,青年虽竟满力量,也充满着苦恼,就像不同年龄段之间的群体,他们很难相互理解每个人在成长的过程中都会经历自身和外界的强烈碰撞。