我正在使用 map
因为我想存储一个对象作为键。
我的问题是 - 我可以像访问普通对象一样访问 map 吗?
例如:
let m = new Map();
let obj = {foo:'bar'};
m[obj] = 'baz';
console.log(m[obj]);
这应该能正常工作吗?还是我需要使用 Map 的 get/set 方法?
我问的原因是因为如果我需要使用 get/set 它会迫使我仔细重构大量代码。
以下是可能需要重构的实际代码示例:
//之前(broker.wsLock是普通对象)
function addWsLockKey(broker, ws, key) {
let v;
if (!( v = broker.wsLock[ws])) {
v = broker.wsLock[ws] = [];
}
if (v.indexOf(key) < 0) {
v.push(key);
}
}
//之后(broker.wsLock 是一个 Map 实例)
function addWsLockKey(broker, ws, key) {
let v;
if (!( v = broker.wsLock.get(ws))) {
v = [];
broker.wsLock.set(ws, v);
}
if (v.indexOf(key) < 0) {
v.push(key);
}
}
有没有办法将 v 设置在与 set() 调用同一行?
最佳答案
如果您想访问Map
对象的实际值,那么您必须使用.get()
和.set()
或各种迭代器。
var m = new Map();
m.set("test", "foo");
console.log(m.get("test")); // "foo"
map
上的常规属性访问,例如:
m["test"] = "foo"
只是在对象上设置常规属性 - 它不会影响实际的 map 数据结构。
我想这样做是为了让您可以与 Map
数据结构的成员分开访问 Map
对象属性,并且两者不应混淆彼此。
此外,常规属性仅接受字符串作为属性名称,因此您无法使用常规属性来索引对象。但是,使用 .set()
和 .get()
时, map 对象具有该功能。
您要求对此问题给出“明确”答案。在 ES6 specification ,您可以查看 .set()
的作用,并看到它在 [[MapData]]
内部插槽上运行,这肯定与对象的属性不同。同样,该规范中也没有任何地方表明使用普通属性访问将访问内部对象[[MapData]]
。因此,您只需查看对象的正常属性访问描述即可。 Map
是一个 Object
,Map
规范中没有任何内容表明普通属性访问的行为应该与任何其他对象的行为不同。事实上,它必须对 Map
对象上的所有方法执行相同的操作,否则如果您碰巧将一个具有相同属性的项目放入 Map
中,这些方法将无法工作。 key 作为方法名称。所以,你的证据包括:
- 一个简单的测试将向您展示属性访问不会在
Map
本身中放入任何内容,而只会放入常规属性。 - 该规范将
Map
描述为一个对象。 - 规范描述了
.get()
和.set()
如何在内部槽[[MapData]]
上进行操作。< - 规范中没有任何内容表明
Map
对象上的属性访问应该与往常不同。 - 如果属性访问确实访问了
MapData
,那么如果您碰巧在Map
中放置了与方法名称冲突的键,您将无法访问方法- 如果是这样的话那就太乱了。
关于javascript - 与普通对象类似地访问 JavaScript 映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44876019/