【问题标题】:Javascript map variableJavascript映射变量
【发布时间】:2025-12-21 01:40:07
【问题描述】:

我希望在 JavaScript 中实现一个 c++ 映射变量类型,但在 Internet 上看不到任何内容。当我使用 SFML 时,我创建了一个 String 类型的 std::map 和 SFML::Texture,这样我就可以在地图中存储一个纹理并通过使用密钥获取纹理值,我将如何在 JavaScript 中实现它?

我想这样做的原因是我想在我的 HTML5 游戏开始时加载所有图像资源,然后我可以调用图像映射并使用键获取图像引用。

【问题讨论】:

    标签: javascript c++


    【解决方案1】:

    JavaScript 中的标准方式只是一个对象:

    var map = {};
    map["any key you like"] = any_value_you_like;
    
    // Also:
    map.any_name_you_like_that_fits_identifer_name_rules = any_value_you_like;
    

    键总是字符串(目前,ES6 将添加符号/名称键),值是任何 JavaScript 值。当您使用点表示法 (obj.foo) 时,属性名称是文字(并受 JavaScript 的 IdentifierName 规则约束);当您使用方括号表示法和字符串 (obj["foo"]) 时,属性名称几乎可以是任何内容(并且可以是任何表达式的结果,例如变量查找)。

    示例:Live Copy

    var map = {};
    map["a"] = "alpha";
    map["b"] = "beta";
    map["c"] = "gamma";
    
    ["a", "b", "c"].forEach(function(key) {
      display("map['" + key + "'] = " + map[key]);
    });
    

    输出:

    地图['a'] = 阿尔法
    地图['b'] = 测试版
    地图['c'] = 伽玛

    dandavis 提出了一个有趣的观点:当你通过{} 创建一个对象时,它会从Object.prototype 继承属性,但是在 ES5 中你可以使用Object.create(null),它不会:

    var map = Object.create(null);
    map["any key you like"] = any_value_you_like;
    
    // Also:
    map.any_name_you_like_that_fits_identifer_name_rules = any_value_you_like;
    

    这样,如果您碰巧有可能使用名称为 toStringvalueOf(在 Object.prototype 上)的键,则在您查找对象时不会得到误报没有明确设置。

    【讨论】:

    • 您可能会考虑使用“Object.create(null)”而不是“{}”,因为结果不会预先填充 toString()、hasOwnProperty()、__proto__、构造函数等属性等等……
    • @dandavis:由于这些是不可枚举的,并且您可以使用自己的属性遮蔽它们,因此几乎不需要。但是,是的,这是一种选择,也是一种有趣的选择。
    • @TJCrowder:嗯,Object.create(null) 的最大优势在于它允许在获取时在应用程序中的任何地方更快地访问属性,因为您可以只抓取 map[anything] 而没有担心调用 hasOwnProperty.call(map, any),或者取出你没有放入的东西。这使它更像一个 C++ 映射。好更新TJ。
    • @dandavis:无论如何,我通常不会打扰hasOwnProperty(通常会为属性名称添加前缀),但正如我所说,这是一个非常有趣的选项(尤其是因为它取消了前缀)。
    • @dandavis:这些读起来很有趣:Creating is markedly slowerObject.create 对比 {},但谁在乎,你不会经常这样做; raw access is about the same 但有(正如我们所说的)误报的可能性; prefixed access is much, much slower。总的来说,Object.create(null) 看起来还不错。
    【解决方案2】:

    您现在可以使用Map 数据结构。它是通过 ES6 在 JavaScript 中引入的,允许创建键值对的集合。与对象不同,映射对象可以将对象和基元作为键和值保存。这是一个例子:

    const items = new Map();
    
    // add items
    items.set('?', 'Dog');
    items.set('?', 'Eagle');
    items.set('?', 'Train');
    items.set(45, 'Number');
    items.set(true, 'Boolean');
    
    // iterate over map
    for (const [key, value] of items) {
        console.log(`${key}: ${value}`);
    }
    

    输出:

    ?: Dog
    ?: Eagle
    ?: Train
    45: Number
    true: Boolean
    

    More examples

    【讨论】: