问题
I want to use an ES6 proxy to trap the following common code:
for (let key in trapped) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
let value = trapped[key];
//various code
}
But after reviewing the proxy documentation, I'm not sure how to do it, mainly because the has
trap trap is for the in
operator, which does not seem to be used in the above code and there is no trap for the hasOwnProperty
operation.
回答1:
You can use the getOwnPropertyDescriptor handler to capture hasOwnProperty()
calls.
Example:
const p = new Proxy({}, {
getOwnPropertyDescriptor(target, property) {
if (property === 'a') {
return {configurable: true, enumerable: true};
}
}
});
const hasOwn = Object.prototype.hasOwnProperty;
console.log(hasOwn.call(p, 'a'));
console.log(hasOwn.call(p, 'b'));
This is specified behavior, not a quirk of a particular implementation:
- Object.prototype.hasOwnProperty calls the abstract
[[HasOwnProperty]]
operation - [[HasOwnProperty]] calls the abstract
[[GetOwnProperty]]
operation [[GetOwnProperty]]
is what getOwnPropertyDescriptor handles
回答2:
I was actually going to answer my question myself, but I was too slow, and others answered it first (and added very useful information besides). Nevertheless, here is the answer I wanted to write, in case it might help someone somehow:
It appears that the getOwnPropertyDescriptor
trap is fired when hasOwnProperty
is called. So you can trap hasOwnProperty
by doing the following:
getOwnPropertyDescriptor(target, name) {
return {
value : target[name],
//use a logical set of descriptors:
enumerable : true,
configurable : true,
writable : true
};
}
The other part is trapping get
and ownKeys
as well:
get(target, name) {
return {}; //replace this with a relevant object
}
//These will be iterated over as part of the for loop
ownKeys() {
return ["RelevantProperty1", "RelevantProperty2"];
}
All in all, since you have to return an array of properties when you trap ownKeys
, using a proxy doesn't seem to make things much better in this use case. I think for the majority of situations, the following would work just as well and be less fragile:
let obj = {};
let keys = ["a" , "b"];
for (let key of keys) {
obj[key] = {}; //relevant object
}
So using a proxy might be overkill.
来源:https://stackoverflow.com/questions/40451694/use-es6-proxy-to-trap-object-hasownproperty