- From: Boris Zbarsky <bzbarsky@mit.edu>
- Date: Tue, 10 Feb 2015 17:34:34 -0500
- 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