简体   繁体   English

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

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

In babel-preset-stage-0 , we can declare static class variable as follow: babel-preset-stage-0 ,我们可以声明静态类变量如下:

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

Is it safe to use Constants.COUNTRY as the key for a ES6 Map or Set ? 使用Constants.COUNTRY作为ES6 MapSet的关键是否安全?

eg. 例如。

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

Is it guaranteed that map.get(Constants.COUNTRY) will always return something ? 是否保证map.get(Constants.COUNTRY)总能返回something

Is the performance as good as using strings as key? 性能和使用字符串一样好吗? Is it safe to use Constants.COUNTRY as eventKey (bootstrap component attribute) for NavItem too? 对于NavItem ,使用Constants.COUNTRY作为eventKey (bootstrap组件属性)也是安全的吗?

Is it also more appropriate to declare it as a variable instead of a class? 将它声明为变量而不是类更合适吗? ie

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

Is it guaranteed that map.get(Constants.COUNTRY) will always return something? 是否保证map.get(Constants.COUNTRY)总能返回一些东西?

For map.get(Constants.COUNTRY) to always return your original value, a couple things have to be true. 对于map.get(Constants.COUNTRY)总是返回原始值,有几件事情必须成立。

  1. You have to make sure that Constants.COUNTRY can never be assigned a different value either because the .COUNTRY property was reassigned or because the Constants object was replaced with something else that had a different .COUNTRY property value. 您必须确保永远不会为Constants.COUNTRY分配不同的值,因为重新分配了.COUNTRY属性,或者因为Constants对象被具有不同.COUNTRY属性值的其他东西替换。

  2. You have to make sure that nobody can ever remove that key from the map object. 您必须确保没有人能够从map对象中删除该密钥。

If you can assure these two things, then yes map.get(Constants.COUNTRY) will always return your desired value. 如果你可以保证这两件事,那么是map.get(Constants.COUNTRY)将始终返回你想要的值。 But, if either of those are not necessarily true, then you are not assured of always getting your value from the map. 但是,如果其中任何一个不一定是真的,那么你不能确保总是从地图中获取你的价值。

You can assure that Constants.COUNTRY cannot be changed by freezing the Constants object or by setting that property to be configurable to it cannot be removed or written to. 你可以保证Constants.COUNTRY不能被冻结改变Constants对象或通过设置该属性是可配置的,以它不能删除或写入。 To assure that the Constants object cannot be replaced, it would be best for it to be const as in your second code block. 为了确保不能替换Constants对象,最好将它作为第二个代码块中的const

I don't know of a way to assure that nobody can call map.delete(Constants.COUNTRY) except by keeping the map object private so foreign code cannot get to it. 我不知道如何确保没有人可以调用map.delete(Constants.COUNTRY)除非将map对象保密,因此外国代码无法访问它。

If you had any reason to want to prevent enumeration of the keys in the map (to make it harder for someone to discover a key perhaps), then you could use a WeakMap instead of a Map . 如果您有任何理由想要阻止枚举地图中的键(以使某人更难以发现键),那么您可以使用WeakMap而不是Map

Is the performance as good as using strings as key? 性能和使用字符串一样好吗?

You'd have to test a specific Javascript implementation to be sure about performance. 您必须测试特定的Javascript实现以确保性能。 There is no required implementation reason that one or the other should be faster - it will just depend upon the internals of the implementation. 没有必要的实现原因,一个或另一个应该更快 - 它将取决于实现的内部。

I created a jsPerf test case to compare string lookups to object lookups. 我创建了一个jsPerf测试用例来比较字符串查找和对象查找。 Feedback is welcome on improving how this is tested/measured, but using the current scheme where I create 10,000 string keys and 10,000 object keys in a map and then compare accessing 1000 of each, I find varying results. 欢迎反馈改进如何测试/测量,但使用当前的方案,我在地图中创建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? 将它声明为变量而不是类更合适吗?

As discussed, your second const form has the advantage that Constants cannot be reassigned. 如上所述,您的第二个const形式的优点是不能重新分配Constants

You can use WeakMap to COUNTRY as key, and something as value. 您可以将WeakMap COUNTRY作为键,将something用作值。 A variable declared with const cannot be deleted. const声明的变量不能删除。 Along with you use of Object.freeze() , wm.get(COUNTRY) should always return something 随着你使用Object.freeze()wm.get(COUNTRY)应该总是返回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 ); 


If requirement is for a variable that cannot be deleted or changed you can use const see Is it possible to delete a variable declared using const? 如果要求是一个无法删除或更改的变量,可以使用const是否可以删除使用const声明的变量? and JSON 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." } */ 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM