You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中以同类对象实例为字典键时,如何避免键被覆盖?

问题:JavaScript对象作为键时被覆盖,无法实现C#字典的效果

我尝试了以下JavaScript代码,但最终字典中只有一个键:

class dog {}
dic = {}

for (let i = 0; i < 3; i++) {
  dic[new dog()] = i;
}

for (var item in dic) {
  console.log(dic[item]);
}

这并非我想要的效果,我希望实现如下C#代码的效果,其输出为0 1 2。看起来上述JS代码中的每个new dog()都被视为同一个对象,导致值被覆盖。请问如何修改JS代码以实现如下C#代码的效果?

using System;
using System.Collections.Generic;

class dog
{
}

public class Program
{
    public static void Main()
    {
        var dic = new Dictionary<object,int>();

        for(var i=0; i<3; i++)
        {
            dic[new dog()] = i;
        }
        
        foreach(var item in dic.Keys)
        {
          Console.WriteLine(dic[item]);
        }
    }
}

问题原因

JavaScript里普通对象作为另一个对象的键时,会被自动转换为字符串[object Object],所以每次new dog()生成的实例都会被转成同一个字符串键,导致后续值直接覆盖之前的。而C#的Dictionary<object, int>是基于对象引用或Equals方法区分键的,和JS普通对象的行为完全不同。

解决方法

方法1:使用Map(推荐)

ES6引入的Map原生支持用对象作为键,它会基于对象的引用关系区分不同键,和C#字典的行为一致:

class dog {}
const dic = new Map();

for (let i = 0; i < 3; i++) {
  dic.set(new dog(), i);
}

// 遍历输出值
for (const value of dic.values()) {
  console.log(value);
}
// 输出:0 1 2

方法2:给对象添加唯一标识作为键

如果必须使用普通对象作为字典容器,可以给每个dog实例添加唯一属性,用该属性作为键:

class dog {
  constructor() {
    // 用Symbol生成全局唯一标识,也可以用自增数字
    this.uniqueKey = Symbol();
  }
}
const dic = {};

for (let i = 0; i < 3; i++) {
  const dogInstance = new dog();
  dic[dogInstance.uniqueKey] = i;
}

for (const key in dic) {
  console.log(dic[key]);
}
// 输出:0 1 2

说明

  • Map是最贴合需求的方案,它的API(set/get/has等)专门针对键值对设计,处理对象键更直观可靠。
  • 用唯一标识作为普通对象键时,Symbol是最优选择,因为每个Symbol都是全局唯一的,不会出现字符串键的冲突问题。

内容的提问来源于stack exchange,提问作者Damn Vegetables

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:08:14