- From: Boris Zbarsky <bzbarsky@MIT.EDU>
- Date: Thu, 08 Aug 2013 18:40:34 -0400
- To: Ian Hickson <ian@hixie.ch>
- Cc: whatwg@lists.whatwg.org
On 8/8/13 5:05 PM, Ian Hickson wrote: > I think the problem is that I have no idea what these ES6 terms are or > what they mean. OK. Which terms, exactly? > Was all this a problem in previous revisions of JavaScript? Or is it some > new problem caused by some new JavaScript feature? It's a "problem", as far as it goes, caused by the ability to get property descriptors at all. In the old world there was no way to explicitly invoke [[DefineProperty]] or check whether something is configurable. So some things were not observable that are now observable, and the ES spec had to define what happens when you observe them. This is not an ES6 issue; ES5 has similar problems, but a bit less clarity (e.g. no Proxy objects in ES5, >>>> "var" needs to be able to define non-configurable properties. >>>> Proxies don't necessarily offer useful guarantees about being able >>>> to define such properties on them, and in particular the behavior >>>> for index/named getters in WebIDL precludes definition of >>>> non-configurable properties of the corresponding kind on the >>>> relevant object. >>> >>> I don't understand what this means, sorry. >> >> Hmm. Which part is unclear? > > I have basically no idea what any of it means. I understand all the > individual words of that paragraph, but I've no idea what they mean when > put next to each other in that order. :-) A property is just an entry in > the bag that is a JS object, what does it mean for it to be or not be > configurable? Ah, ok. So in ES5 there is a concept of a "property descriptor". There is both an internal representation of property descriptors and a way to get JS objects that represent a property descriptor: Object.getOwnPropertyDescriptor. See ECMA-262 edition 5 section 8.10 for details on how property descriptors work, but fundamentally a property descriptor for an existing property describes how it's set up. A property descriptor can also be used to create new properties via Object.defineProperty. Every property descriptor has two booleans it stores: [[Enumerable]] and [[Configurable]]. [[Enumerable]] controls whether the property shows up in for..in enumeration. [[Configurable]] controls how the property descriptor for this property can change. In particular, if [[Configurable]] is false, then the values of [[Configurable]], [[Enumerable]], [[Get]], [[Set]], and [[Writable]] for this property cannot change in the future ([[Value]] can still change if this is a value property that is [[Writable]]). All property manipulation in ES5 and later is defined in terms of property descriptors. For example, the definition of [[Put]] (which is the thing that happens on "foo.bar = something") in ES5 section 8.12.5 does gets the property descriptor and then looking at that descriptor and deciding what to do based on that ([[GetOwnProperty]] and [[GetProperty]] return property descriptors, somewhat non-obviously). > A proxy is something that passes incoming requests from one > object to another object A Proxy in ES6 is a particular kind of JS object that has pointers to two other objects: a target and a handler. The target is what requests get passed to, if desired. The handler is basically a mapping from MOP names to JS functions implementing the relevant MOP operation. So for example, an object with an indexed getter is defined in WebIDL by defining that it has special implementations for three MOP operations: [[GetOwnProperty]], [[DefineProperty]], and [[Delete]]. If you wanted to implement such an object in JS, there is no way to do this in ES5. In ES6, you would create a Proxy whose target is just a vanilla object for storing expandos and the proto link and whose handler does the steps defined by WebIDL for those three operations. Note that your description of a proxy above is certainly implementable as a Proxy, but a Proxy can also implement other things (again, like things with indexed or named getters as currently specced). See http://people.mozilla.org/~jorendorff/es6-draft.html#sec-8.5 for the full-on spec bits. > what does it mean for a proxy to have a property? If it returns something other than undefined from [[GetOwnProperty]]. >> Er... That's a cross-site information leak. > > How so? The names of the IDL attributes and methods on Window objects are > the same on all Window objects (WindowModal notwithstanding), and the > non-IDL properties aren't enumerable cross-origin. getOwnPropertyNames returns all own properties, not just enumerable ones. > "For members that return objects (including function objects), each > distinct effective script origin that is not the same as the Window > object's Document's effective script origin must be provided with a > separate set of objects. These objects must have the prototype chain > appropriate for the script for which the objects are created (not those > that would be appropriate for scripts whose script's global object is the > Window object in question)." Mmm... I don't think this works very well for Window. > (same effective origin) Sure. >> in that situation two different origins become the same origin and the >> fact that they have different Window objects for the same current window >> ends up observable. > > Well, what the spec says now is that when the script changes effective > origin, it also changes its prototypes and so forth, essentially. Does any UA do this? I would be somewhat surprised if this were web compatible, and even more surprised if it were implementable in practice and if any UA wanted to implement it.... > We (the Web community) can change what's allowed and what isn't allowed. > We do so all the time. Sure, but changing this makes it very hard to reason about ES, in very undesirable ways. This has been pretty extensively hashed out on es-discuss and public-script-coord... And more to the point it seems unnecessary to throw out useful invariants in this case just so we can preserve a particular specification device. >> If an object (in this case a WindowProxy, since that's what the script >> is working with) ever claims that it has a non-configurable property for >> some property name, ES requires that it _always_ do that from that point >> on. > > That's fine. The Window will keep having that property. The WindowProxy > object's own properties can't be examined The WindowProxy is the object the script has. It's the object [[GetOwnProperty]] (via Object.getOwnPropertyDescriptor) is called on. So the above requirement about the property not disappearing if it's non-configurable applies to the WindowProxy. Which is why WindowProxy can't ever claim to have non-configurable properties... It would violate basic language invariants. -Boris
Received on Thursday, 8 August 2013 22:41:02 UTC