An idea to extend the functionality of Proxy objects.

Ranando King kingmph at gmail.com
Sat Jan 13 01:41:58 UTC 2018


You're right about the mistake with Object.seal. I wasn't too focused on
that part when writing the example code. So are you suggesting that I also
prepare a fully detailed rewrite of the invariant rules for comparison?

On Fri, Jan 12, 2018 at 6:44 PM, Isiah Meadows <isiahmeadows at gmail.com>
wrote:

> Make sure to compare your changes to the [invariants of the essential
> internal methods][1], since changes to them would require some
> *significant* justification. And yes, your proposal would require
> changes to them. (I'm not a TC39 member, but I've read up enough about
> their decisions to make some educated guesses, and core changes tend
> to be met with extreme skepticism.)
>
> Also, note that you probably meant to, in `SourceFile.js`, use
> `Object.seal(obj)`, not `obj.seal()` (it's a static method, not an
> instance method).
>
> [1]: https://tc39.github.io/ecma262/#sec-invariants-of-
> the-essential-internal-methods
> -----
>
> Isiah Meadows
> me at isiahmeadows.com
>
> Looking for web consulting? Or a new website?
> Send me an email and we can get started.
> www.isiahmeadows.com
>
>
> On Fri, Jan 12, 2018 at 5:38 PM, Ranando King <kingmph at gmail.com> wrote:
> > I have an idea I’d like to propose with regards to Proxy objects. I would
> > like to make a change to spec section 6.1.7.3 (as seen in the latest
> draft).
> > The change is as follows:
> >
> > The Internal Methods of Objects of an ECMAScript engine must conform to
> the
> > list of invariants specified below. Ordinary ECMAScript Objects as well
> as
> > all standard exotic objects in this specification maintain these
> invariants.
> > ECMAScript Proxy objects maintain these invariants by means of runtime
> > checks on the result of traps invoked on the [[ProxyHandler]] object
> using
> > either the corresponding traps on the [[ProxyHandler]] should the needed
> > trap be defined, or the default internal method otherwise.
> >
> > Put simply, the change that I’m requesting would have the runtime checks
> > verify the selfconsistency of the results returned by the
> [[ProxyHandler]]
> > object instead of testing the [[ProxyHandler]] results against the
> target.
> > The rationale behind this change is to allow Proxy objects the freedom to
> > behave in a manner that is inconsistent with the behavior that would have
> > been should the target have been accessed directly, while still requiring
> > that the consistency of the behavior of the essential internal methods be
> > upheld. In this way, a Proxy object would be able to project new
> properties
> > for a proxied target even if the target object is not extensible, or even
> > completely hide non-configurable properties. The requirement to do so
> would
> > be implementation of the appropriate [[ProxyHandler]] methods so as to
> > satisfy all of the corresponding invariants for all implemented handlers.
> > The ECMAScript engine would then see results consistent with
> expectations,
> > despite the fact that the results are inconsistent with the actual
> nature of
> > the proxied target object.
> >
> > An example might be the case of a library to mock objects.
> >
> > /* SourceFile.js */
> > var obj = { bar: "The real bar. Accept no imitations!", fubar: "Always
> has
> > been." };
> > obj.seal();
> >
> > export default obj;
> >
> > /* TestFile.js */
> > import testObj from "SourceFile";
> >
> > var mock = new Proxy(testObj, {
> >   has: function(target, key) {
> >     var retval = false;
> >     if (key == "foo") { //add the foo property
> >       retval = true;
> >     }
> >     else if (key != "bar") { //hide the bar property
> >       retval = (key in target);
> >     }
> >
> >     return retval;
> >   },
> >   ownKeys: function(target) {
> >     var retval = Reflect.ownKeys(target);
> >     var barIndex = retval.indexOf(bar);
> >
> >     if (barIndex != -1)
> >       retval.splice(barIndex, 1);
> >
> >     retval.push("foo");
> >     return retval;
> >   },
> >   defineProperty: function(target, key, descriptor) {
> >     var retval = true;
> >     if ((key == "foo") || (key == "bar")) {
> >       retval = false;
> >     }
> >     else {
> >       Reflect.defineProperty(target, key, descriptor);
> >     }
> >
> >     return retval;
> >   },
> >   get: function(target, key) {
> >     var retval = undefined;
> >
> >     if (key == "foo") {
> >       retval = "You got the fake property!"
> >     }
> >     else if (key != "bar") {
> >       retval = Reflect.deleteProperty(target, key);
> >     }
> >
> >     return retval;
> >   },
> >   set: function(target, key, value) {
> >     var retval = false;
> >     if ((key != "foo") && (key != "bar"))
> >       retval = Reflect.set(target, key);
> >     }
> >     return retval;
> >   },
> >   deleteProperty: function(target, key) {
> >     var retval = false;
> >     if ((key != "foo") && (key != "bar"))
> >       retval = Reflect.deleteProperty(target, key);
> >     }
> >     return retval;
> >   },
> >   getOwnPropertyDescriptor: function(target, key) {
> >     var retval;
> >     if (key == "foo") {
> >       retval = {
> >         enumerable: true,
> >         writable: false,
> >         configurable: false,
> >         value: "You got the fake property!"
> >       };
> >     }
> >     else if (key != "bar") {
> >       retval = Reflect.getOwnPropertyDescriptor(target, key);
> >     }
> >     return retval;
> >   }
> > });
> >
> > console.log(mock.fubar); // "Always has been"
> > console.log(mock.foo);   // #1
> > console.log(mock.bar);   // #2
> >
> >
> > Currently, if the above code were run, an error would be thrown at
> comment
> > #1. Even if that line was commented out, an error would be thrown at
> comment
> > #2. With my proposed change, the code would run successfully. Comment #1
> > would be "You got the fake property!" and comment #2 would be undefined.
> As
> > a matter of completeness, if the handler only contained the "get" and
> "set"
> > methods, this code would throw an error just as it currently would. The
> > reason that it works with all of the handlers this that these handlers
> > ensure that a consistent description of the is being presented to the
> > interpreter since the interpreter would rely on the methods of the proxy
> > object's handler to supply the data needed to validate the response of
> the
> > original call.
> >
> > _______________________________________________
> > es-discuss mailing list
> > es-discuss at mozilla.org
> > https://mail.mozilla.org/listinfo/es-discuss
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20180112/79fa53c9/attachment-0001.html>


More information about the es-discuss mailing list