javascript - 属性访问器与映射集方法

标签 javascript

有没有办法让下面的代码要么

  1. m[k] = v
  2. 上引发错误
  3. 调用 m[k] = v 自动转换为 m.set(k, v)

如果可能的话,我更喜欢解决方案 1。

// Imagine I write that somewhere
const m = new Map();
m.set("a", "alice");

// And at some point someone else write:
m["b"] = "bob";    // m = Map { 'a' => 'alice', b: 'bob' }
// Expecting "bob" to appear here: 
for (const [k, v] of m){
    console.log(k, v);
}

请注意,当我说其他人时,这个其他人在不久的将来可能就是我。理想情况下,我希望有一个只修改实例化 const m = new Map() 的解决方案。例如 const m = safe(new Map())

最佳答案

为了防止添加属性,您可以使用:

 Object.freeze(map);

但是,这不会引发错误。为了能够在属性访问上抛出错误,您必须使用代理,但是由于这不能直接在 map 上工作(因为它们具有不会通过代理反射(reflect)的内部属性),您必须镜像所有方法在一个对象中,并在该对象上使用代理:

 function safe(map) {
  return new Proxy({
    get(k) { return map.get(k); },
    set(k, v) { return map.set(k, v); }
    // .... others
 }, {
   set() { throw new Error("property setter on Map"); }
 });
}

您还可以捕获 Proxies getter 以直接链接到 map (尽管不确定副作用):

function safe(map) {
  return new Proxy({ }, {
   set() { throw new Error("property setter on Map"); },
   get(target, prop, receiver) {
    return typeof map[prop] === "function" ? map[prop].bind(map) : map[prop];
   }
  });
}

关于javascript - 属性访问器与映射集方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55459456/

相关文章:

javascript - 使用下划线/lodash 电子邮件列表/集合随机播放和配对

javascript - AngularJS 解析插值属性

javascript - 在不插入另一个对象的情况下更新 useState

Javascript - AmCharts 使用图例隐藏和显示图形

javascript - 如何将上部转换为下部并用破折号替换空格?

javascript - 固定 Tipsy 工具提示在 Raphaël 路径节点上的位置

javascript -/page1/和/page2/显示相同 - Express

javascript - Rails CORS:ActionController::RoutingError(没有路由匹配 [OPTIONS] "/batches"):

javascript - 如何区分何时使用 xargs 调用 Node

php - 良好的 JSON 但浏览器抛出错误