Proxies can do a better, more thorough job of breaking encapsulation. ```js var log = []; String = new Proxy(String, { construct(target, newTarget, args) { log.push(args); return Reflect.construct(target, newTarget, args); } });
(function () { var s = String; var private = function () { return new s("cat"); } var public = function () { return private(); } return public; })() ``` There's no equivalent with Object.observe. I could also redefine String as a sloppy mode function and use `arguments.callee` or `Function.prototype.callee` to get the `private` function, which would even work in ES3. There's ways to break encapsulation already, that don't involve Object.observe. And you can't observe references purely contained within a closure. On Wed, Nov 4, 2015, 00:51 Coroutines <corouti...@gmail.com> wrote: > Okay, so I've been making a lot of noise on this list in the last few > days about Proxy and Object.observe(). I thought I would try to put > up some example code to show why both should stay, but > Object.observe() usage should be restricted so it's not web-accessible > (debug use only). > > var target = {} // this is the object we want to "observe", either > with Object.observe() or through a Proxy object. > var p = new Proxy(target, {}); // this is the proxy where we can add > indirection, validation, or simply watch for events as we attempt to > operate on target > > With Object.observe() we would be dealing with the same reference, > `target`. If we used a Proxy we would replace the `target` reference > with that of the proxy to ensure that every operation on `target` is > going through the handling code of the Proxy: > > target = p; // and now only the Proxy holds an internal reference to > the original object (side question: is this accessible through > p.valueOf()?) > > Anyway, my issue with Object.observe() is that you can observe > operations on an object from within closures, from references to > `target` that were made before you began observing. > > My example is that you have global access to `String`, but a module > usually wraps all its implementation details and private functions in > a (function (){})() and returns either a constructor or an object with > public-facing functions. > > (function () { > var s = String; > var private = function () { return new s("cat"); } > var public = function () { return private(); } > return public; > })() > > Please accept this poor example with awful identifiers as code you > might see in the wild. > > Now: > > Should you be able to Object.observe() String and see that it is being > used to construct "cat" within the private function, within this > closure? > > String is accessible and referenced from many places, so observing > that particular object that is very public seems reasonable. I am on > the fence about if this should be allowed because while String is > quite 'visible', what is happening within that closure should not be. > Closures are used for organization and to hide implementation details > (of course). > > The reason I think Proxy does it "right" is because you would need to > replace the reference to String with a Proxy that wraps String before > the closure makes a localized reference to it and exports its public > function. I think this still respects the "black box" way closures > are used to hide what they do. Proxy requires setup before references > are made, Object.observe() can begin watching for changes at any time. > This is because a Proxy is a separate object, and therefore has a > separate identity - while Object.observe() works with the original > object. I want to say that because the closure seals away the > reference to String, that String should not be observable within the > closure - even if you have access to String outside the closure. If > you wrap String before executing the closure, then you would of course > have the ability - but only if you proxy it before the closure. To > *me* that would feel correct. > > Anyway, I'm going to try to talk less I've been sending too many > messages. I come from Lua and I love that this functionality exists > in Javascript exists in its own form. I did a lot of fun things in > Lua so this is pretty personal to me if I want to continue having fun > in JS. > > I want Object.observe() to stay for tricky debug situations, but I > think it would break information hiding/encapsulation on the web by > allowing you to observe changes made through existing private > references. Proxy is what people should use, O.o() can be a private > sexy debug tool? > > FIN. > _______________________________________________ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss