【问题标题】:Is it possible to "freeze" a Set (or Map)?是否可以“冻结”一个集合(或地图)?
【发布时间】:2015-10-09 03:26:40
【问题描述】:

虽然Set 是一个对象,但Object.freeze() 作用于对象的属性,显然 Map 和 Set 不使用这些属性:例如

让 m = 新地图(); Object.freeze(m); m.set('key', 55); m.get('key') ==> 55

这是 Chrome 中的行为,我希望它是标准的。

我了解可以(有时)将 Set 或 Map 转换为普通对象,然后冻结该对象。但随后在解冻版本和冻结版本之间更改密钥访问权限。

【问题讨论】:

标签: javascript object dictionary set


【解决方案1】:

有趣的问题,但目前似乎不是 SetMap 对象上直接支持的功能。

以下是我可以考虑使用Set 对象作为指导的一些变通方法:

  1. 您可以创建一个代理对象,删除 .add().clear().delete(),但允许代理访问所有其他仅读取数据的方法。这将隐藏对实际 Set 对象的访问,因此无法直接访问它并提供对所有其他方法的代理访问。

  2. 您可以在给定的Set 实例上覆盖.add().clear().delete(),其方法不执行任何操作或引发异常以防止修改。如果您使这些覆盖方法不可配置,然后在对象上执行.freeze(),则无法放回这些方法。可以直接在Set 对象上使用Set.prototype.add 来绕过它。

【讨论】:

  • 谢谢。同意。第一个似乎很多工作,一个输了instanceof Set。其次,覆盖.add() 等似乎更容易,让它静默失败或引发错误。至于“仍然绕过”,对我来说,冻结的主要优点不是绝对安全,而是保护自己,就像键入变量一样。
  • 现在已经有几年了,但我想我会提到,如果你用未定义的方法覆盖列出的方法,而不是方法,那么解决方案 #2 效果最好。如果您尝试将它们作为方法调用,那将引发错误,并且对于一次性使用来说是最容易的。如果您想要使用子类化 Set 或 Map 的更通用解决方案,请记住,当在所有浏览器中子类化时,这些解决方案无法正常工作,因此#1 中的代理是一种更好的可重用方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 2021-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多