繁体   English   中英

属性访问器 vs. Map set 方法

[英]Property accessors vs. Map set method

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

  1. m[k] = v上引发错误或
  2. 调用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);

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

 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];
   }
  });
}

你可以使用代理

 let m = new Map(); m["a"] = "alice"; m = new Proxy(m, { set(target, name, receiver) { throw "Setting values is forbidden!"; } }); console.log(m["a"]); // you can read value m["b"] = "bob"; // setting value will throw exception

您可以使用代理对象。 实例化它,第一个参数是你想要的任何 Map 的实例化。

const m = new Proxy(new Map(), {
    get(target, name, receiver) {
        return target.get(name);
    },
    set(target, name, receiver) {
        // 1. Comment in to allow error to be thrown.
        // throw new Error(`Cannot set property for ${name}`);

        // 2. Comment in to allow setting via bracket syntax.
        // target.set(name, receiver);
    }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM