下面的代码是否可以通过
m[k] = v
或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())
之类的。
答案 0 :(得分:1)
要防止添加属性,可以使用:
Object.freeze(map);
但是,这不会引发错误。为了能够在属性访问中引发错误,您必须使用Proxy,但是由于它不能直接在Maps上运行(因为它们的内部属性无法通过Proxy反映出来),因此您必须镜像所有方法在一个对象中,并在该对象上使用Proxy:
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吸气剂以直接链接到地图(尽管不确定副作用):
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];
}
});
}
答案 1 :(得分:0)
您可以使用proxy
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
答案 2 :(得分:0)
您可以使用Proxy对象。将第一个参数实例化为您想要的任何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);
}
});