跳至內容
Astera Technology

分組名稱可任意寫,別撞上物件內建鍵

用 Map 計分組,toString 也只是普通名稱。

下載完整個案資料及參考答案 ↓

先追這段程式

按 markup、toString、markup 三個名稱累計,分組次序依首次出現的鍵。

完整原始程式
const labels=['markup','toString','markup'];const counts=new Map();
for(const label of labels)counts.set(label,(counts.get(label)??0)+1);
console.log(JSON.stringify([...counts]));
確實的 console 輸出
[["markup",2],["toString",1]]
值與執行位置
輸入名稱輸入後個數鍵次序
markup1markup
toString1markup, toString
markup2markup, toString

結果為何如此

Map.get 讀已存項目,不查原型屬性。未有鍵得到 undefined,?? 才補零再加一;更新 markup 不會改首次插入位置。若用普通物件作字典,須另處理自有屬性或空原型。

比較另一種寫法

空普通物件的 toString 來自原型,讀到的是函式,不是未有個數。以下只核類型,不用各引擎可能不同的函式文字。

另開的有限例子
const counts={};const value=counts['toString']??0;
console.log(JSON.stringify({own:Object.hasOwn(counts,'toString'),type:typeof value,zero:value===0}));
另一寫法的輸出
{"own":false,"type":"function","zero":false}

試清邊界

Map 的數字鍵 1,和文字鍵 "1" 是否同一項?

查看參考答案

不是,兩者是不同鍵。Map 可存非文字鍵;本例的分組輸入則全是固定文字。

重新建立的邊界例子
const counts=new Map([[1,'number'],['1','text']]);
console.log(JSON.stringify({size:counts.size,number:counts.get(1),text:counts.get('1')}));
邊界例子的輸出
{"size":2,"number":"number","text":"text"}

原始例子檔案