ES6 可以安全地使用静态 class 变量作为 Map 的键吗?

ES6 safe to use static class variable as key for Map?

babel-preset-stage-0中,我们可以声明静态class变量如下:

class Constants {
  static COUNTRY = Object.freeze({
      NAME: 'Germany',
      DESCRIPTION: 'placeholder',
  })
}

使用 Constants.COUNTRY 作为 ES6 MapSet 的密钥安全吗?

例如。

const map = new Map();
map.add(Constants.COUNTRY, something);

是否保证map.get(Constants.COUNTRY)永远returnsomething

性能和使用字符串作为键一样好吗?将 Constants.COUNTRY 用作 eventKey(bootstrap 组件属性)也用于 NavItem 是否安全?

是否也将其声明为变量而不是class更合适? 即

const Constants = Object.freeze({
  COUNTRY: Object.freeze({
      NAME: 'Germany',
      DESCRIPTION: 'placeholder',
  })
}) 

您可以使用 WeakMapCOUNTRY 作为键,使用 something 作为值。不能删除用 const 声明的变量。随着你使用 Object.freeze()wm.get(COUNTRY) 应该总是 return something

  const wm = new WeakMap;

  const COUNTRY = Object.freeze({
    NAME: 'Germany',
    DESCRIPTION: 'placeholder',
  });

  wm.set(COUNTRY, "something");

  // error when "use strict"
  delete wm;
  delete COUNTRY;

  COUNTRY.NAME = 123;

  console.log(
    wm.get(COUNTRY)
  );
  
  console.log(
    COUNTRY
  );
  
  console.log(
    wm
  );


如果需要的是无法删除或更改的变量,您可以使用 const 参见 JSON

"use strict";

// `Constants` cannot be changed or deleted
const Constants = `{
  "NAME": "Germany",
  "DESCRIPTION": "placeholder"
}`;

console.log(
  JSON.parse(Constants)
);

// delete Constants;
/*
Error: {
  "message": "Uncaught SyntaxError: Delete of an unqualified identifier in strict mode."
}
*/

Is it guaranteed that map.get(Constants.COUNTRY) will always return something?

为了 map.get(Constants.COUNTRY) 始终 return 您的原始值,有几件事必须是真实的。

  1. 您必须确保永远不会为 Constants.COUNTRY 分配不同的值,因为 .COUNTRY 属性 已重新分配,或者因为 Constants 对象被替换为具有不同 .COUNTRY 属性 值的其他对象。

  2. 您必须确保没有人可以从 map 对象中删除该密钥。

如果你能保证这两件事,那么是的map.get(Constants.COUNTRY)将永远return你想要的值。但是,如果其中任何一个不一定为真,那么您将无法保证始终从地图中获取您的价值。

您可以通过冻结 Constants 对象或将 属性 设置为可配置以确保无法更改 Constants.COUNTRY,使其无法删除或写入。为确保无法替换 Constants 对象,最好将其设置为 const,就像您的第二个代码块中那样。

我不知道有什么方法可以确保没有人可以调用 map.delete(Constants.COUNTRY),除非将 map 对象设为私有,这样外部代码就无法访问它。

如果您有任何理由想要阻止枚举映射中的键(可能使某人更难发现键),那么您可以使用 WeakMap 而不是 Map.

Is the performance as good as using strings as key?

您必须测试特定的 Javascript 实施才能确定性能。一个或另一个应该更快的实现没有必要的理由——它只取决于实现的内部结构。

我创建了一个 jsPerf test case 来比较字符串查找和对象查找。欢迎提供有关改进的反馈 tested/measured,但使用当前方案,我在映射中创建 10,000 个字符串键和 10,000 个对象键,然后比较访问每个键的 1000 个,我发现不同的结果。

Chrome is ~20% slower to access the object keys.
Firefox is ~20% slower to access the string keys.
Edge is ~27% slower to access the string keys.

Is it also more appropriate to declare it as a variable instead of a class?

如前所述,您的第二个 const 表单的优点是 Constants 无法重新分配。