possible excessive proxy invariants for Object.keys/etc??

Tom Van Cutsem tomvc.be at gmail.com
Wed Nov 21 12:27:11 PST 2012

2012/11/21 Allen Wirfs-Brock <allen at wirfs-brock.com>

> I'd be more favorably inclined towards freezing than I am towards copying.
>  But, as you know,  ES5 does not currently produce frozen objects in these
> situations. I feel uncomfortable about enforcing a frozen invariant for
> traps where that invariant is not provided by the corresponding ordinary
> object behavior.  Perhaps I could get over that or perhaps incompatibility
> applying that requirement to ordinary objects wouldn't break anything.

While the arrays produced by Object.keys etc. aren't frozen, there's an
implicit guarantee that those arrays will not further be modified
implicitly by any other operation in the program. Of course a program can
choose to explicitly mutate it. But there's no magical action-at-a-distance.

Currently, we provide the same guarantee in the face of proxies by
"defensively copying" the trap result into a fresh array. Requiring the
trap result to be frozen feels OK to me, except that it doesn't play well
with the current default of automatically forwarding:

var p = Proxy(target, { })
Object.keys(p) // error: "keys" trap did not return a frozen array

var p = Proxy(target, { keys: function(t) { return
Object.freeze(Object.keys(t)); })
Object.keys(p) // now it works

One way to get rid of this irregularity is indeed to make Object.keys
always return frozen arrays. I don't think it would hurt performance, as
implementations already aren't allowed to reuse arrays returned from
Object.keys (of course they can always cheat as long as they don't get

> Regardless, freezing and testing for frozen is, itself, not a cheap
> operation.  It requires iterating over all the property descriptors of an
> object.  If we are going to build in a lot of checks of for frozen objects
> perhaps we should just make frozen (and possibly) sealed object level
> states rather than a dynamic check of all properties.  Essentially we could
> internally turn the [[Extensible]] internal property into a four state
> value:  open,non-extensible,sealed,frozen.  It would make both freezing and
> checking for frozen much cheaper.

As Andreas mentioned, for normal objects, isFrozen checks can be optimized
to O(1).
For proxies, if we leave in the derived isFrozen trap, the check could also
be O(1).

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20121121/6e3c5a95/attachment.html>

More information about the es-discuss mailing list