Experimental implementation of Object.observe & JS Utility library now available

Brendan Eich brendan at mozilla.org
Sat Aug 18 15:06:03 PDT 2012


Rafael Weinstein wrote:
> On Fri, Aug 17, 2012 at 8:03 PM, Brendan Eich<brendan at mozilla.org>  wrote:
>> Mark S. Miller wrote:
>>
>>> On Fri, Aug 17, 2012 at 6:49 PM, Brendan Eich<brendan at mozilla.org
>>> <mailto:brendan at mozilla.org>>  wrote:
>>>
>>>      All praise to Raf et al., my concern is that something
>>>      synchronous, plus event loop concurrency and setImmediate, would
>>>      suffice to bootstrap the rather more elaborate proposal on top of
>>>      the simpler O.p.watch like fundament.
>>>
>>>      This is not to say we shouldn't standardize higher-level APIs, and
>>>      instead push that off on library authors to write, and users to
>>>      download. There's a delicate balance here. We often screw up
>>>      higher-level abstractions in annoying ways, but perhaps that risk
>>>      is worth taking.
>>>
>>>      What I'm really getting at is this: why not expose the synchronous
>>>      primitive and e.l.c. building blocks as well?
>>>
>>>
>>> A synchronous observation mechanism provides an attacker too many
>>> opportunities for a plan interference attack. If you'll recall, an earlier
>>> synchronous proposal died for this reason.
>
> That is an excellent reason.

It is, and I should have recited it to the Y U no kids but I hadn't 
found it expressed concisely. I should have looked harder -- it was 
recorded in the May 2011 meeting notes:

https://mail.mozilla.org/pipermail/es-discuss/2011-May/014748.html

"""
Allen: This allows people to break into abstractions by putting observers on
objects they don't own.
DaveH: Proxies are deliberately less powerful than this in that they don't
allow you to attach behaviors to arbitrary objects that you don't own.
MarkM: Notification happening synchronously is a security problem.
Observers can run at times when code doesn't expect malicious changes.
"""


>   I have two others:
>
> 1) It's a terrible design pattern to encourage. Webdevs will
> absolutely use it and learn the hard way, just like we did with
> Mutation Events that it works fine when we start, but down the road
> lies nothing but pain and suffering.

This is not a complete reason -- "see mutation events" -- but I know 
that history too. What I remember mostly dissuading developers was bad 
performance -- use a mutation event listener and your DOM got slow -- 
but any more detailed history would be helpful, here if not in the spec 
(more below).

> 2) Synchronous doesn't actually exist -- it's a false option.
>
> To explain: When people talk about "synchronous" what they expect is
> that they will be notified concurrent with the event happening (this
> *is happening*). The expectation is that when they are invoked they
> are observing the world as the event is describing.
>
> This is the appeal of synchronous delivery. Here's the rub: unless you
> plan to only allow a single observer per object, then you have to pick
> someone to go first. And unless you plan to prevent that person from
> further mutating the object, the next guy to be called may not observe
> the world in the state suggested by the "synchronous" call.

Synchronous != synchronized.

>
> In fact, an arbitrary number of mutations can always have occurred by
> the time any given observer is called, so it's just dishonest API
> which pretends that a single thing has happened. The correct thing is
> to inform each observer what *set* of things has happened.

Right, the "is happening" => "has happened" implies the set.

> So the only questions are:
>
> 1) Do you mislead the consumer with API which suggests that only one
> thing will has happened
> 2) If not, when do you deliver the set of things: immediately after
> the mutation occurs, at the end of the turn or ask the UA to schedule
> a future task.
>
> Referring back to my reason (1) This question was debated extensively
> with DOM Mutation Observers and unanimously decided that the end of
> the turn was the only good solution. "immediately" puts all code in
> danger of having its runtime assumptions invalidated after every
> operation which mutates objects and "future task" is far too late to
> be useful for most almost all use cases.

Thanks, this is good and perhaps we don't need to dig up and summarize 
the mutation observer debate. But I think the spec (proposal and 
ECMA-262) should record an informative note or summary or something.

>> Thanks, I recall -- but this needs to be stated clearly in the spec. I hear
>> from people all the time asking Y U no Object.prototype.watch.
>
> Which spec? Is there something you're wanting to see in the text of
> the Object.observe proposal?

As a start, and edited for concision, but yes: something that makes the 
case as crisply as possible. Then I'd expect Allen can incorporate it 
appropriately into ES6 drafts and we can point people at it (I can, at 
least!).

Thanks for taking the time to write this up.

/be
>
>> /be
>>
>>> Object.observe has been carefully designed to strike a good balance
>>> between providing non-malicious code useful new powers without providing
>>> attackers significant new attack opportunities. The core principle is that a
>>> client of an object can anyway observe changes to observable state
>>> asynchronously by polling between turns. And a client of an object, if it
>>> receives control during a turn, can poll while it has control. To a first
>>> approximation, Object.observe can be understood as an optimization of
>>> polling. It is actually more powerful than that, but in ways that are
>>> beneficial without IMO creating significant new hazards.
>>>
>>>
>>>      /be
>>>
>>>      Brandon Benvie wrote:
>>>
>>>          I agree on the above with regard to Proxies. They are awesome
>>>          and allow for incredible things, but Object.observe fills a
>>>          different use case that I think is more common at at the user
>>>          standpoint or at least library standpoint. When you look
>>>          around at the major JS libraries that exist the problem they
>>>          are trying to solve (after DOM normalization) is data-binding.
>>>          Proxy can be used to solve this for new objects or wrapped
>>>          objects, but that's overkill and may have performance
>>>          consequences, and has no support for working with existing
>>>          objects. Proxy and observe end up filling two completely
>>>          different use-cases, and I would venture to say that observe
>>>          is the one that most people could make better use of if they
>>>          had it in their hands today.
>>>          _______________________________________________
>>>          es-discuss mailing list
>>>          es-discuss at mozilla.org<mailto:es-discuss at mozilla.org>
>>>
>>>          https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>      _______________________________________________
>>>      es-discuss mailing list
>>>      es-discuss at mozilla.org<mailto:es-discuss at mozilla.org>
>>>
>>>      https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>>
>>>
>>> --
>>>      Cheers,
>>>      --MarkM
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>


More information about the es-discuss mailing list