Use ES6 proxy to trap Object.hasOwnProperty

*爱你&永不变心* 提交于 2019-12-13 15:46:10

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!