An update on Object.observe

Isiah Meadows isiahmeadows at gmail.com
Wed Nov 4 06:08:26 UTC 2015


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 <coroutines at 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 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/20151104/7f8f583b/attachment-0001.html>


More information about the es-discuss mailing list