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 Map
或 Set
的密钥安全吗?
例如。
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',
})
})
您可以使用 WeakMap
到 COUNTRY
作为键,使用 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 您的原始值,有几件事必须是真实的。
您必须确保永远不会为 Constants.COUNTRY
分配不同的值,因为 .COUNTRY
属性 已重新分配,或者因为 Constants
对象被替换为具有不同 .COUNTRY
属性 值的其他对象。
您必须确保没有人可以从 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
无法重新分配。
在babel-preset-stage-0
中,我们可以声明静态class变量如下:
class Constants {
static COUNTRY = Object.freeze({
NAME: 'Germany',
DESCRIPTION: 'placeholder',
})
}
使用 Constants.COUNTRY
作为 ES6 Map
或 Set
的密钥安全吗?
例如。
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',
})
})
您可以使用 WeakMap
到 COUNTRY
作为键,使用 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 您的原始值,有几件事必须是真实的。
您必须确保永远不会为
Constants.COUNTRY
分配不同的值,因为.COUNTRY
属性 已重新分配,或者因为Constants
对象被替换为具有不同.COUNTRY
属性 值的其他对象。您必须确保没有人可以从
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
无法重新分配。