如何在JavaScript中以完整对象为键检查存在性并分配唯一随机数?
解决对象作为Map键的唯一性判断问题
问题原因
你原代码里用普通对象fontMap[fontObj]的方式行不通,因为JavaScript普通对象的键只能是字符串或Symbol类型。当你把对象作为键时,JS会自动调用对象的toString()方法,把所有对象都转成"[object Object]",导致不同的fontObj都会被当成同一个键,根本没法区分唯一性。
解决方案
根据你对“唯一fontObj”的定义(是引用相同还是结构属性值完全一致),可以用以下两种方案:
方案1:结构属性一致即视为同一(推荐)
如果只要postscript、style、family三个属性值都相同,就认为是同一个fontObj,那可以把这三个属性拼接成一个唯一字符串作为键,这样能精准区分不同的字体组合。
代码示例:
// 生成唯一键的工具函数 const getUniqueFontKey = (fontObj) => { // 按固定顺序拼接属性,避免JSON.stringify的属性顺序问题 return `${fontObj.postscript}|${fontObj.style}|${fontObj.family}`; }; // 遍历段落的逻辑 const fontMap = {}; for (const paragraph of yourParagraphs) { // 替换成你的段落遍历逻辑 const fontObj = paragraph.font; // 假设从段落中获取fontObj const fontKey = getUniqueFontKey(fontObj); if (fontMap[fontKey]) { console.log(`Already found: ${JSON.stringify(fontObj)} and the random number is ${fontMap[fontKey]}`); } else { fontMap[fontKey] = Math.random(); } }
也可以用JSON.stringify(fontObj)生成键,但要注意如果fontObj的属性顺序不固定(比如有的对象先写style,有的先写postscript),会生成不同的字符串,导致误判,所以固定顺序拼接更稳妥。
方案2:仅同一对象引用视为同一
如果只有完全相同的对象引用才算是同一个fontObj(比如你的fontObj是从同一个对象池里取的,不会有结构相同但引用不同的情况),可以直接用ES6的Map,它支持直接以对象作为键:
代码示例:
const fontMap = new Map(); for (const paragraph of yourParagraphs) { const fontObj = paragraph.font; if (fontMap.has(fontObj)) { console.log(`Already found: ${JSON.stringify(fontObj)} and the random number is ${fontMap.get(fontObj)}`); } else { fontMap.set(fontObj, Math.random()); } }
这个方法的局限性是,两个结构完全一样但不同引用的对象,会被Map当成不同的键,所以只适合引用唯一的场景。
内容的提问来源于stack exchange,提问作者sal3jfc
相关产品推荐
相关产品推荐

