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