访问JavaScript映射类似于普通对象 [英] Access JavaScript map similarly to plain object

查看:57
本文介绍了访问JavaScript映射类似于普通对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用地图

因为我想将对象存储为键.

because I want to store an object as a key.

我的问题是-我可以像访问普通对象一样访问地图吗?

My question is - can I access a map the same way I would access a plain object?

例如:

let m = new Map();
let obj = {foo:'bar'};
m[obj] = 'baz';
console.log(m[obj]);

这应该可以正常工作吗,还是我需要使用Map的get/set方法?

is this supposed to work correctly as is, or do I need to use the get/set methods of a Map?

我问的原因是因为如果我需要使用get/set,它将迫使我仔细重构大量代码.

The reason I ask is because if I need to use get/set it forces to me to carefully refactor a lot of code.

这是现实生活中可能需要重构的代码示例:

Here is a real life example of code that may need to be refactored:

//之前(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);
  }
}

有什么方法可以在set()调用的同一行上设置v?

is there some way to set v on the same line as the set() call?

推荐答案

如果要访问 Map 对象的实际值,则必须使用 .get() .set()或各种迭代器.

If you want access to the actual values of the Map object, then you have to use .get() and .set() or various iterators.

var m = new Map();
m.set("test", "foo");
console.log(m.get("test"));    // "foo"

Map 上的常规属性访问,例如:

Regular property access on a Map such as:

m["test"] = "foo"

仅在对象上设置常规属性-不会影响实际的地图数据结构.

just sets a regular property on the object - it does not affect the actual map data structure.

我想这是通过这种方式完成的,因此您可以与 Map 数据结构的成员分开访问 Map 对象属性,并且不要将两者与彼此.

I imagine it was done this way so that you can access the Map object properties separately from the members of the Map data structure and the two shall not be confused with one another.

此外,常规属性将仅接受字符串作为属性名称,因此您不能使用常规属性为对象建立索引.但是,使用 .set() .get()时,地图对象具有该功能.

In addition, regular properties will only accept a string as the property name so you can't use a regular property to index an object. But, map objects have that capability when using .set() and .get().

您要求对此做出确定的"答案.在 ES6规范中,您可以看一下 .set()的功能,看看它在 [[MapData]] 内部插槽上运行,该插槽肯定与对象的属性不同.同样,在该规范中没有任何地方说明使用普通属性访问将访问内部对象 [[MapData]] .因此,您只需要看到为对象描述了常规的属性访问. Map 是一个 Object ,并且 Map 规范中没有任何内容表明普通属性访问的行为应与对其他任何对象的行为有所不同.实际上,它必须对 Map 对象上的所有方法执行相同的操作,否则,如果您碰巧将具有相同内容的项放入 Map 中,则它们将无效.键作为方法名称.因此,您证明了这一点:

You asked for a "definitive" answer to this. In the ES6 specification, you can look at what .set() does and see that it operates on the [[MapData]] internal slot which is certainly different than the properties of an object. And, likewise, there is no where in that spec where it says that using normal property access would access the internal object [[MapData]]. So, you'll have to just see that normal property access is describe for an Object. A Map is an Object and there's nothing in the Map specification that says that normal property access should act any different than it does for any other object. In fact, it has to act the same for all the methods on the Map object or they wouldn't work if you happened to put an item in the Map with the same key as a method name. So, you're proof consists of this:

  1. 一个简单的测试将向您显示,属性访问不会在 Map 本身中放置任何内容,而只是普通属性.
  2. 该规范将 Map 描述为对象.
  3. 该规范描述了 .get() .set()如何在内部插槽 [[MapData]] 上运行.
  4. li>
  5. 规范中没有任何内容说明对 Map 对象的属性访问应该与以往不同.
  6. 如果属性访问确实访问了 MapData ,那么如果您碰巧在 Map 中放置了与方法名称冲突的键,则将无法访问方法-如果是这样的话,那将是一团糟.
  1. A simple test will show you that property access does not put anything in the Map itself, only a regular property.
  2. The spec describes a Map as an object.
  3. The spec describes how .get() and .set() operate on the internal slot [[MapData]].
  4. There's nothing in the spec that says property access on a Map object should work any different than it always does.
  5. If property access did access the MapData, then you would not be able to access methods if you happened to put a key in the Map that conflicted with a method name - that would be a mess if that was the case.

这篇关于访问JavaScript映射类似于普通对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆