Save Object.observe()! (please) + make WeakMap/WeakSet observable.

Isiah Meadows isiahmeadows at
Wed Nov 4 05:55:27 UTC 2015

You can't get anything related to actual object access from Object.observe.
If you observe String, you can only get the following events:

- "add": String.newProp = value
- "update": String.existingProp = newValue
- "delete": delete String.prop
- "reconfigure": Object.defineProperty(String, ...)
- "setPrototype": String.__proto__ = newProto
- "preventExtensions": Object.preventExtensions(String)

None of these can detect access. Only changes and removal.

And from each change, the callback is called with a list of objects with
the following properties:

- "type": one of the types of actions above
- "object": the object being mutated
- "name": the name of the property
- "oldValue": if the action was "update", "delete", or "setPrototype", then
the value it previously was. Otherwise, this property doesn't exist.

You can only get the old value from objects that existed before the
closure. So it's already not necessarily unavailable outside the closure.
You could achieve similar by replacing the original reference with a proxy
before the closure, or even in theory by employing getters and setters. So
it's not really breaking encapsulation beyond what's already possible in
ES6. You can still leak closure references left and right with proxies. The
difference is the fact you don't have to explicitly replace the reference
beforehand. It could be implemented as an implicit reference replacement
under the hood.

As for detecting object accesses, that remains impossible with
Object.observe. The only thing you can do with it that you can't with
proxies is to observe the global object itself, an uncommon use case.
Everything else can be done with proxies. This just makes a common case

On Tue, Nov 3, 2015, 23:10 Coroutines <coroutines at> wrote:

> On Tue, Nov 3, 2015 at 7:33 PM, Isiah Meadows <isiahmeadows at>
> wrote:
> > There's a reason Object.observe is async: it prevents you from changing
> how
> > the value is first assigned, so it can't work like a proxy. And question:
> > how does it let you see hidden closures?
> In JS it is common to wrap everything in a (function (){})() for
> organization and/or encapsulation purposes.  I would wrap a 'module'
> in that, and within that module I might define local references to
> common classes/libraries like: var string = require('String');
> (example)
> You cannot reach and redefine that private reference to String within
> that module, but you do still have a reference to String from /where
> you are/.  If you Object.observe(String) from another place you can
> see events generated by the closed-over, private functions of that
> module.
> In my opinion this is bad, as it breaks the expectation of privacy you
> have with a closure.
> I think both should stay, but Object.observe() should not be
> accessible "from the web" and only used for debugging.  With Proxy you
> can't watch events from existing references that are hidden behind
> closures.  Proxy creates a separate, 2nd object so it does not have
> the same identity.  If you want to make sure you catch all events on
> the target object you have to replace all the references to the target
> with the proxy.  This is good, and does not allow closures to leak
> events from hidden references to the same target you're watching
> outside the closure.
> _______________________________________________
> es-discuss mailing list
> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list