- From: Ojan Vafai <ojan@chromium.org>
- Date: Tue, 3 Jan 2012 18:18:45 -0800
- To: Cameron McCormack <cam@mcc.id.au>
- Cc: "public-script-coord@w3.org" <public-script-coord@w3.org>, Boris Zbarsky <bzbarsky@mit.edu>, Travis Leithead <Travis.Leithead@microsoft.com>, Allen Wirfs-Brock <allen@wirfs-brock.com>, Ian Hickson <ian@hixie.ch>
- Message-ID: <CANMdWTvMkUXez=miUeRCeP36yO+JpAea9o0=MFZ8djFPMnN1Mg@mail.gmail.com>
On Tue, Jan 3, 2012 at 4:51 PM, Cameron McCormack <cam@mcc.id.au> wrote:
> In https://www.w3.org/Bugs/**Public/show_bug.cgi?id=8241<https://www.w3.org/Bugs/Public/show_bug.cgi?id=8241>we finally settled on the name resolution order for the window object to be
> the following:
>
> 1. Own properties on window (which would include JS builtin
> global properties like Array, Object, etc.) and global variables
> 2. Properties from the prototype chain (which would include
> "constructor" & event listener properties)
> 3. Frames
> 4. Global scope polluter
>
> Since the Window interface is also declared with
> [ReplaceableNamedProperties], allowing assignments to window object
> properties to shadow named properties, the following document should alert
> "[object Window]" and then "a":
>
> <!DOCTYPE html>
> <iframe name=x></iframe>
> <script>
> alert(x);
> x = "a";
> alert(x);
> </script>
>
> The question I have (which Ojan raised in the content of
> http://code.google.com/p/**chromium/issues/detail?id=**80591<http://code.google.com/p/chromium/issues/detail?id=80591>)
> is what the following document should alert:
>
> <!DOCTYPE html>
> <iframe name=x></iframe>
> <script>
> alert(x);
> </script>
> <script>
> var x;
> alert(x);
> </script>
>
> I had thought that current specs would cause this to alert "[object
> Window]" and then "undefined" (which I think is preferable to the
> alternative) but now looking closer I don't think this is true.
>
> Here's current browser behaviour:
>
> Firefox nightly: "[object Window]" / "[object Window]"
> Opera.next: "[object Window]" / "undefined"
> Safari/WebKit nightly: "[object DOMWindow]" / "[object DOMWindow]"
> Chrome nightly: "[object DOMWindow]" / "[object DOMWindow]"
> IE 10pp1: "[object Window]" / "undefined"
>
Firefox behaves differently for frames and elements I believe (or maybe
names versus IDs?).
<div id="a"></div><script>alert(a);</script> // Alerts "[object
HTMLDivElement]"
<div id="a"></div><script>alert(a);var a;</script> // Alerts "undefined"
<div id="a"></div><script>var a;alert(a);</script> // Alerts "undefined"
My strong preference is that declaring a variable should cause it to shadow
(i.e. alert undefined above). Not shadowing has been a frequent source of
bugs for the Closure Compiler in WebKit. Shadowing makes it much easier to
reason about how library code will behave when embedded in a page.
All the people I've spoken to about this in the WebKit community are fine
with changing WebKit once the behavior is clearly specced.
I don't have strong opinions about what path to take in the spec to achieve
this behavior.
This is why I think currently the specs support the Firefox/Safari/Chrome
> behaviour:
>
> * The ECMAScript spec says that the global environment (the one affected
> by var statements in global code) is an object environment record
> with its binding object being the global object.
>
> http://people.mozilla.org/~**jorendorff/es5.html#sec-10.2.3<http://people.mozilla.org/~jorendorff/es5.html#sec-10.2.3>
>
> * Named properties are exposed on the window object through the
> [[GetOwnProperty]] definition in Web IDL.
>
> http://dev.w3.org/2006/webapi/**WebIDL/#getownproperty<http://dev.w3.org/2006/webapi/WebIDL/#getownproperty>
>
> * Since the Window interface has a getter but no setter, the descriptors
> for the named properties are exposed as
> { configurable: true, enumerable: true, writable: false, value: V }
>
> * There is no custom [[HasProperty]] defined in Web IDL, so when called
> on the window object with the name of a named property it will return
> true.
>
> * When the second <script> element in the document is run, the var
> statement will be run as described in:
>
> http://people.mozilla.org/~**jorendorff/es5.html#sec-10.5<http://people.mozilla.org/~jorendorff/es5.html#sec-10.5>
>
> and in that algorithm we'll get to step 8.b, to determine whether a
> variable binding for the name "a" already exists. That step calls
> the HasBinding operation for object environment records:
>
> http://people.mozilla.org/~**jorendorff/es5.html#sec-10.2.**1.2.1<http://people.mozilla.org/~jorendorff/es5.html#sec-10.2.1.2.1>
>
> which returns the result of [[HasProperty]], which in this case will
> be true. That'll mean step 8.c.i, which calls CreateMutableBinding,
> is never run.
>
>
> Note that if the var statement has a variable assignment, such as in
>
> <!DOCTYPE html>
> <iframe name=a></iframe>
> <script>
> var a = 1;
> </script>
>
> then the named property *will* be shadowed, due to the use of
> [ReplaceableNamedProperties] on the Window interface. It's basically the
> same case as just having `a = 1;` as the script, due to the var declaration
> not having any effect.
>
>
> If we want var statements without a variable assignment to shadow named
> properties, then we can't keep [[GetOwnProperty]] returning property
> descriptors for them while [[HasProperty]] returns true for them, without
> violating the ECMAScript spec.
>
> We could either make [[HasProperty]] return false for named properties on
> window despite [[GetOwnProperty]] returning a property descriptor. Or, we
> could make the window object have a custom [[GetProperty]] instead of
> [[GetOwnProperty]], so that [[HasProperty]] returns false and
> [[GetOwnProperty]] returns undefined, while fetching the property off the
> object still gives you the named property value.
>
> So two questions:
>
> 1. Just to confirm, is having assignment-less var statements shadow
> named properties the behaviour we want?
>
> 2. Is either of the above alternatives for achieving it preferable, or
> is there another, better way I haven't thought of?
>
> Thanks,
>
> Cameron
>
Received on Wednesday, 4 January 2012 06:32:08 UTC