2011/9/3 David Bruant <david.bru...@labri.fr> > If i recall correctly, this proposal was on hold because of the fixed > properties proposal (only getPropertyDescriptor I think). > The idea was that if there is a getPropertyDescriptor trap, then it > became impossible (or it would just require some proto-climbing with > some performance issue?) to guarantee the invariants of non-configurable > properties. But now that I think about it, i can't remember exactly what > was the annoying use case. > > Adding Tom in copy. Maybe he'll remember. >
The issue was that with the earlier fixed properties proposal (the one that stopped trapping access to cached non-configurable properties), the proxy would also cache inherited non-configurable property descriptors, and in doing so the properties were converted into "own" properties of the proxy (Object.getOwnPropertyDescriptor would find them in the cache). In the latest design of the fixed properties proposal, inherited non-configurable properties are simply no longer checked. So the short answer: the getPropertyDescriptor trap is no longer problematic, so neither should Object.getPropertyDescriptor. If you want to understand why I think getPropertyDescriptor is no longer problematic in the latest design, read on (apologies for the lengthy explanation, this stuff is hard to formulate concisely!) - When the getPropertyDescriptor trap returns a non-configurable property, in the absence of any other information, the caller cannot know whether that property is an own or an inherited property. Concretely: var desc = Object.getPropertyDescriptor(obj, "foo"); // does "desc" describe an own or inherited "foo"? Can't know at this point. - If the property is inherited, then even if it is non-configurable, it may still be shadowed later by a configurable property. Say our |obj| example object inherits from |proto1|, which inherits from |proto2|. Assume "foo" was defined as a non-configurable property on |proto2|. Then our |desc| object above denotes a non-configurable property. Now, assume "foo" is later added to |proto1| as a configurable property. Re-executing the call to getPropertyDescriptor will then result in "desc" denoting a configurable property. That is within the bounds of ES5.1 behavior. If |obj| would be a proxy with a FixedHandler, the FixedHandler should not complain that "foo" was previously reported as non-configurable. That is why inherited descriptors returned by getPropertyDescriptor are not checked for invariants. - Now assume a different scenario in which "foo" is an own, non-configurable property of |obj|. The only way for code to find out that "foo" is indeed an own, non-configurable property is to call Object.getOwnPropertyDescriptor. Doing so will cause the FixedHandler to mark "foo" as a fixed own property. Now, if code calls Object.getPropertyDescriptor(obj, "foo"), the getPropertyDescriptor trap will find "foo" marked as an own property, so it _knows_ it can't be inherited and it must check the validity of the returned result. If getPropertyDescriptor were to return a configurable descriptor at this stage, the FixedHandler will throw. Thus, the following interaction could occur if |obj| were a "faulty" proxy whose getPropertyDescriptor trap reports "foo" as a configurable property while at the same time its getOwnPropertyDescriptor trap reports it as a non-configurable property (which is inconsistent): > var desc1 = Object.getPropertyDescriptor(obj, "foo"); // desc1 = { ... , configurable: true } > var desc2 = Object.getOwnPropertyDescriptor(obj, "foo"); // desc2 = { ..., configurable: false } // (now FixedHandler knows that "foo" was observed as an own non-configurable property) > var desc3 = Object.getPropertyDescriptor(obj, "foo"); TypeError: can't report "foo" as configurable as it was previously exposed as a non-configurable own property I hope this clarifies why I think getPropertyDescriptor is no longer problematic. Cheers, Tom
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss