如何将JavaScript类实例添加到对象?键异常及实例匹配问题排查
问题解析:对象作为键时的字符串转换与检测问题
嘿,我来帮你把这个问题拆解清楚~
为什么obj显示{[object Object]: true}?
在JavaScript中,普通对象(用{}创建的对象)的键只能是字符串或者Symbol类型。当你尝试用一个对象(比如你的temp实例)作为键时,JS会自动调用这个对象的toString()方法,把它转换成字符串来作为键名。
对于默认的自定义类实例来说,继承自Object的toString()方法返回的就是固定字符串"[object Object]",所以你看到的obj里的键就是这个转换后的结果啦。
为什么temp2 in obj和temp in obj都返回true?
因为temp和temp2都是test类的实例,它们调用默认的toString()方法后,得到的都是"[object Object]"。这意味着,你给obj[temp] = true和obj[temp2] = true本质上都是在给同一个键"[object Object]"赋值。所以当你用in操作符检测时,不管用哪个实例,都是在检查这个字符串键是否存在,自然都会返回true。
怎么实现用实例作为唯一键?
如果你想让每个test实例都作为obj里的唯一键,有两种常用方案:
方案1:使用Map(推荐)
Map是ES6引入的集合类型,它的键可以是任意类型的对象,不会被自动转换为字符串,能准确区分不同的实例:
class test{ constructor(x){ this.x = x; } } const temp = new test(10); const temp2 = new test(10); const myMap = new Map(); myMap.set(temp, true); console.log(myMap.has(temp)); // 输出 true console.log(myMap.has(temp2)); // 输出 false
方案2:自定义toString方法
如果你坚持要用普通对象,可以给test类自定义toString()方法,让每个实例返回唯一的字符串标识:
class test{ static idCounter = 0; // 用静态计数器生成唯一ID constructor(x){ this.x = x; this.instanceId = test.idCounter++; } toString() { return `test-instance-${this.instanceId}`; } } const temp = new test(10); const temp2 = new test(10); const obj = {}; obj[temp] = true; console.log(temp in obj); // 输出 true console.log(temp2 in obj); // 输出 false console.log(obj); // 输出 { 'test-instance-0': true }
内容的提问来源于stack exchange,提问作者anon
相关产品推荐
相关产品推荐

