W3C home > Mailing lists > Public > public-script-coord@w3.org > January to March 2015

Re: Defining a [[Set]] internal method for platform objects

From: Boris Zbarsky <bzbarsky@mit.edu>
Date: Tue, 10 Feb 2015 17:34:34 -0500
Message-ID: <54DA877A.6030907@mit.edu>
To: Domenic Denicola <d@domenic.me>, "public-script-coord@w3.org" <public-script-coord@w3.org>
On 2/10/15 4:59 PM, Domenic Denicola wrote:
> I don't suppose there's a way to change the results for Three and Four that both gets at least two browsers and simplifies the proposal?

That's a good question.  For reference, here are Three and Four:

    // named setter on object, no overridebuiltins
    sessionStorage.getItem = "b";
    alert("Three: " + sessionStorage.getItem);
    alert("Four: " + Storage.prototype.getItem.call(sessionStorage,
"getItem"));

and here's current browser behavior:

Firefox: Performing the set calls the named setter, which is why you get 
"Four: b".  Performing the get ignores the named property, because the 
Storage interface is not [OverrideBuiltins] and see the "getItem" on 
Storage.prototype, so "Three" ends up being a function object.

IE: In IE, Storage seems to have [OverrideBuiltins] behavior.  So the 
set calls the named setter, then the .getItem get ends up calling the 
named getter and hence you get "Three: b".  You can test this pretty 
easily like so:

   sessionStorage.setItem("clear", "hey");
   alert(sessionStorage.clear);

and see that this alerts a function object in non-IE browsers, but the 
string "hey" in IE.  IE's behavior for DOMStringMap matches the Firefox 
behavior for Storage.

Chrome/Safari (they have the same behavior): During the set, the named 
setter is not invoked at all.  Instead an ordinary property is defined 
on the sessionStorage object, with name "getItem" and value "b".  During 
the get, the value of this property is, obviously, gotten.

We _could_ implement the Chrome/Safari behavior here, I think.  It 
would, I believe, require the following changes from my suggested spec:

1)  In [[Set]] don't invoke the named setter in the non-overridebuiltins 
case if the property name would shadow something on the proto chain.

2)  Stop invoking the named setter at all from [[DefineOwnProperty]].

This would mean that Object.defineProperty on a DOM proxy with a named 
setter never invokes the named setter, since it's only a [[Set]] that 
can invoke it.

I'm not sure whether you'd consider this simpler or not.  ;)

Note that in Chrome, Firefox, and IE Object.defineProperty with an 
_indexed_ name does invoke the indexed setter.  See 
<http://jsfiddle.net/p6obqavd/2/>.  It doesn't seem to do that in Safari.

Oh, and actually in Chrome it looks like defineProperty with an index 
will invoke a _named_ setter when there is no indexed setter.  That's 
just bizarre, given that it doesn't invoke it for non-indexed property 
names.  See <http://jsfiddle.net/p6obqavd/3/> and compare to Firefox/IE 
(which call the named setter for both defineProperty calls) and Safari 
(which doesn't call it for either one).

So whatever we do with [[DefineOwnProperty]], I propose _not_ matching 
Blink there.  ;)

> I apologize for not having the fortitude to dive into the details and attempt to come up with such a modification myself.

No need to apologize.  I _totally_ understand.

-Boris
Received on Tuesday, 10 February 2015 22:35:08 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 10 February 2015 22:35:08 UTC