// 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