<div dir="ltr"><div dir="ltr" style="font-size:12.8px">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?</div><div class="gmail-yj6qo gmail-ajU" style="margin:2px 0px 0px;font-size:12.8px"></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 12, 2018 at 6:44 PM, Isiah Meadows <span dir="ltr"><<a href="mailto:isiahmeadows@gmail.com" target="_blank">isiahmeadows@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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>
<div><div class="h5"><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>
</div></div>> ______________________________<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>
</blockquote></div><br></div>