是否可以 "freeze" 一个 Set(或 Map)?
Is it possible to "freeze" a Set (or Map)?
虽然 Set
是一个对象,但 Object.freeze()
作用于对象的属性,显然 Map 和 Set 不使用这些属性:例如
let m = new Map();
Object.freeze(m);
m.set( 'key', 55);
m.get( 'key' ) ==> 55
这是 Chrome 中的行为,我希望它是标准的。
我知道可以(有时)将 Set 或 Map 转换为普通对象,然后冻结该对象。但随后在未冻结和冻结版本之间更改密钥访问权限。
有趣的问题,但目前似乎不是 Set
或 Map
对象上直接支持的功能。
以下是我可以想到的一些解决方法,使用 Set
对象作为指南:
您可以创建一个删除 .add()
、.clear()
和 .delete()
的代理对象,但允许代理访问所有其他只读取数据的方法。这将隐藏对实际 Set
对象的访问,因此无法直接访问它并提供对所有其他方法的代理访问。
您可以在给定的 Set
实例上覆盖 .add()
、.clear()
和 .delete()
,方法不执行任何操作或抛出异常防止修改。如果您使这些重写方法不可配置,然后对对象执行 .freeze()
,则这些方法无法恢复。可以直接在 Set
对象上使用 Set.prototype.add
来绕过它。
虽然 Set
是一个对象,但 Object.freeze()
作用于对象的属性,显然 Map 和 Set 不使用这些属性:例如
let m = new Map(); Object.freeze(m); m.set( 'key', 55); m.get( 'key' ) ==> 55
这是 Chrome 中的行为,我希望它是标准的。
我知道可以(有时)将 Set 或 Map 转换为普通对象,然后冻结该对象。但随后在未冻结和冻结版本之间更改密钥访问权限。
有趣的问题,但目前似乎不是 Set
或 Map
对象上直接支持的功能。
以下是我可以想到的一些解决方法,使用 Set
对象作为指南:
您可以创建一个删除
.add()
、.clear()
和.delete()
的代理对象,但允许代理访问所有其他只读取数据的方法。这将隐藏对实际Set
对象的访问,因此无法直接访问它并提供对所有其他方法的代理访问。您可以在给定的
Set
实例上覆盖.add()
、.clear()
和.delete()
,方法不执行任何操作或抛出异常防止修改。如果您使这些重写方法不可配置,然后对对象执行.freeze()
,则这些方法无法恢复。可以直接在Set
对象上使用Set.prototype.add
来绕过它。