- From: Cameron McCormack <cam@mcc.id.au>
- Date: Wed, 04 Jan 2012 11:51:45 +1100
- To: "public-script-coord@w3.org" <public-script-coord@w3.org>
- CC: Ojan Vafai <ojan@chromium.org>, Boris Zbarsky <bzbarsky@mit.edu>, Travis Leithead <Travis.Leithead@microsoft.com>, Allen Wirfs-Brock <allen@wirfs-brock.com>, Ian Hickson <ian@hixie.ch>
In 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) 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" 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 * Named properties are exposed on the window object through the [[GetOwnProperty]] definition in Web IDL. 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 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 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 00:55:05 UTC