// AggressiveMap ctor.
// Like Map but only allows getting properties that exist,
// and doesn't allow setting properties at all.
const AggressiveMap = function(arg) {
return new Proxy(new Map(arg), {
// Property getter
get: function(realThing, name, receiver) {
if (!(name in realThing)) {
throw new Error("No "+name+" for you!");
}
// No idea why this is necessary, but if I don't special case 'size', I get
// "Uncaught TypeError: Method Map.prototype.size called on incompatible receiver [object Object]"
// on Chrome 59.
if (name === 'size') { return realThing.size; }
let answer = Reflect.get(realThing, name, receiver);
if (typeof answer === 'function') {
// https://stackoverflow.com/questions/43236329/why-is-proxy-to-a-map-object-in-es2015-not-working/43236808#answer-43236808
answer = answer.bind(realThing);
}
return answer;
},
// Property setter
set: function(realThing, name, value, receiver) {
// Don't allow setting any properties.
throw new Error("No "+name+" for you!");
// But here's how to do it if we wanted to allow it.
return Reflect.set(realThing, name, value, receiver);
},
});
}; // AggressiveMap ctor
// Exercise it a bit
const map = AggressiveMap([['a',1],['b',2],['c',3]]);
map.set('d', 4);
map.delete('c');
console.log("map.get('b') = "+JSON.stringify(map.get('b')));
console.log("Iterating:");
for (const [key,value] of map) {
console.log(" "+JSON.stringify(key)+" -> "+JSON.stringify(value));
}
console.log("map.size = "+JSON.stringify(map.size));
map['moose'] = 'foo'; // No moose for you!
console.log("map['moose'] = "+JSON.stringify(map['moose'])); // No moose for you! (gets here if you comment out previous line)
NOTE: Requires a browser supporting ES2015's Proxy.
我猜你将不得不与额外的属性 – Pete
@Pete扩展对象类型是什么额外的属性?等等,你在想我想让他们理解那些错误的名字吗? Noooooooooo,我希望他们在使用它们的时候抛出一个错误! –
如果你将它们映射为额外的属性,你可以让这些属性在使用时抛出一个异常 - 这是你能够让它们在脸上可以这么说,但不扩展初始对象的唯一方法,你可以不能进入这些propeties,他们将永远不明确 – Pete