Like many clever solutions, it's been done before: 
http://exploringjs.com/es6/ch_proxies.html#sec_proxy-use-cases (in 28.4.2). A 
co-worker found this after we discussed implementing a guard class for our 
code. So triple apologies for my postings. 

Also good idea on adding the extra level of prototype to the guard class. FWIW, 
inspect and toJSON could be added to Guarded.prototype (with value undefined, 
of course)  to avoid going through the proxy for the inspect (a Node thing) and 
toJSON probes. The might be some Symbols you want to add too though looking at 
the list of standard probed symbols doesn't suggest any compelling ones. Maybe 
Symbol.toPrimitive? 

----
Alex Kodat

From: T.J. Crowder [mailto:[email protected]] 
Sent: Friday, September 8, 2017 2:51 AM
To: Alex Kodat <[email protected]>
Cc: [email protected]
Subject: Re: Not own property getters

On Fri, Sep 8, 2017 at 2:28 AM, Alex Kodat
<mailto:[email protected]> wrote:
> Head slap. The following does what I want with essentially zero
> overhead (at least with V8)...

:-) Clever solution for situations where you can't detect these statically in 
advance, nice one.

You can turn it up to 11 by avoiding hitting the proxy for the 
`Object.property` properties, by making the base guard prototype derive from 
your proxy and put the `Object.property` features on it. That way, 
`hasOwnProperty`, `valueOf`, etc. aren't impacted by passing through the proxy. 
(See my `Guarded` below.)
https://jsperf.com/throw-on-missing-property-scenarios

You'll also want to handle `toJSON` and other spec-defined optional properties 
or properties implementations commonly look for outside spec (is that what your 
`inspect` property is?). And set `constructor`.

```js
function Guarded() {
}
Guarded.prototype = Object.create(new Proxy(Object.freeze(Object.create(null)), 
{
  get: (target, prop) => {
    if (prop === "toJSON" || prop === "inspect") {
        return undefined;
    }
    throw Error("Bad property: " +  prop);
  }
}));
Object.defineProperties(Guarded.prototype, 
Object.getOwnPropertyDescriptors(Object.prototype));
Object.defineProperty(Guarded.prototype, "constructor", {
    value: Guarded,
    configurable: true
});

class Foo extends Guarded {}
```

-- T.J. Crowder

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to