I'm declaring myDictionary
as an object which is filled by the user (key/ values)
But for the matter of defensive programming, I want to make sure if the user gives __proto__
as the key to the dictionary object, with the value of "some value"
, he/she will be able to use it, but as you know when calling myDictionary.__proto__
the Object prototype setter/getter will be called.
One solution that I've found for this is creating the object with null
as a prototype, so there will be no __proto__
setter/getter in its prototype. But the problem is you also won't have the other Object's methods.
I'm longing to see if anyone here can solve the question (any way to polyfill the Object methods while saving the performance?)
They try to define the __proto__
as a key in the dictionary.
let myDictionary = {};
let key = prompt("What's the key?", "__proto__");
myDictionary [key] = "some value";
alert(myDictionary [key]); // [object Object], not "some value"!
solving the problem by creating the object with null
as a prototype:
let myDictionary = Object.create(null);
let key = prompt("What's the key?", "__proto__");
myDictionary[key] = "some value";
alert(myDictionary[key]); // "some value"
Or is there a way to assign property with the __proto__
key without messing with the Object prototype's getter/setter ??
CodePudding user response:
You can use a proxy to hide undesired properties in the object.
Since you want to have certain properties with custom values, a map of those can be provided (an object does not work). The return of the createObject
function will be a new object that checks each key and checks it against the provided map of defined keys. This way you can essentially have custom properties on your object without sacrificing its prototypal methods such as toString()
.
The implementation of this behavior or done with a Proxy that accepts a getter for each lookup on the object, inside the getter the accessed property is intercepted and if it's defined, that value is returned, otherwise, the normal value is returned.
function protectedObject(target = {}, definedKeys = new Map()) {
const handler = {
get(target, prop) {
if (definedKeys.has(prop)) return definedKeys.get(prop);
return target[prop];
}
};
return new Proxy(target, handler);
}
const obj = protectedObject({
test: 123
}, new Map([
["__proto__", "some value"]
]));
console.log(obj.test);
console.log(obj.__proto__);
console.log(obj.toString());
alert(obj[prompt("What's the key?", "__proto__")]);
All Object.prototype
methods are intact since this creates a real object (just proxied).