Not own property getters

Alex Kodat alexkodat at gmail.com
Fri Sep 8 13:52:07 UTC 2017


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:tj.crowder at farsightsoftware.com] 
Sent: Friday, September 8, 2017 2:51 AM
To: Alex Kodat <alexkodat at gmail.com>
Cc: es-discuss at mozilla.org
Subject: Re: Not own property getters

On Fri, Sep 8, 2017 at 2:28 AM, Alex Kodat
<mailto:alexkodat at gmail.com> 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



More information about the es-discuss mailing list