与普通对象类似地访问JavaScript映射

时间:2017-07-02 23:22:08

标签: javascript node.js dictionary

我正在使用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);
  }
}

有没有办法在与set()调用相同的行上设置v?

1 个答案:

答案 0 :(得分:2)

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

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

Map上的常规媒体资源访问权限,例如:

m["test"] = "foo"

只是在对象上设置一个常规属性 - 它不会影响实际的地图数据结构。

我想这是以这种方式完成的,这样你就可以从Map数据结构的成员中分别访问Map对象属性,并且两者不会相互混淆。

此外,常规属性只接受字符串作为属性名称,因此您无法使用常规属性来索引对象。但是,使用.set().get()时,地图对象具有此功能。

你要求一个&#34;明确的&#34;回答这个问题。在ES6 specification中,您可以查看.set()做了什么,并看到它在[[MapData]]内部插槽上运行,这肯定与对象的属性不同。而且,同样地,在该规范中没有说明使用普通属性访问将访问内部对象[[MapData]]。因此,您必须只看到对象描述的正常属性访问。 MapObjectMap规范中没有任何内容表明普通属性访问应该与其他任何对象的行为不同。实际上,它必须对Map对象上的所有方法采取相同的行为,否则如果您碰巧将Map中的项目与方法相同的密钥放在Map中,它们将无法工作名称。所以,您的证据包括:

  1. 一个简单的测试将告诉您,属性访问不会在Map本身中放置任何内容,只会是常规属性。
  2. 规范将.get()描述为对象。
  3. 该规范描述了.set()[[MapData]]如何对内部广告位Map进行操作。
  4. 规范中没有任何内容表明MapData对象上的属性访问应该与以往不同。
  5. 如果属性访问确实访问了Map,那么如果您碰巧在[HttpGet] public ActionResult Index() { return View(); } [HttpPost] public ActionResult SubscriberLookUp(Member filter) { Member model = new Model(); //retrieve data from db based on filter and store result in a session model = (Member)Session["UserSession"]; return PartialView("MemberGrid", model); } 中放入与方法名称冲突的密钥,那么您将无法访问方法 - 这将是一个混乱如果是这样的话。