|
View:
New views
9 Messages
—
Rating Filter:
Alert me
|
|
|
The precise meaning of "For each named own enumerable property name P of O"What is the behavior when the body of the loop may have side effects? There are a number of these for the Object.* hooks, but I'm most specifically considering Object.defineProperties, in the case when some getter executed in the body of that loop (also in ToPropertyDescriptor) results in a new property being added, a future property being removed, a property being readded with the same name (does it attempt to define the property twice?) -- all the usual enumeration hazards, but most particularly the last one because of potential weirdness of defining the same property twice with conflicting attributes between the two property descriptors (if the appropriate behavior were specified to trigger that).
Jeff _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
RE: The precise meaning of "For each named own enumerable property name P of O"ES5 section 12.6 (for-in statement) says:
The mechanics and order of enumerating the properties (step 6.a in the first algorithm, step 7.a in the second) is not specified. Properties of the object being enumerated may be deleted during enumeration. If a property that has not yet been visited during enumeration is deleted, then it will not be visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are guaranteed not to be visited in the active enumeration. ES3 says pretty much the same thing with minor wording tweaks. >-----Original Message----- >From: es-discuss-bounces@... [mailto:es-discuss- >bounces@...] On Behalf Of Jeff Walden >Sent: Wednesday, August 12, 2009 1:04 PM >To: es-discuss@... >Subject: The precise meaning of "For each named own enumerable property >name P of O" > >What is the behavior when the body of the loop may have side effects? >There are a number of these for the Object.* hooks, but I'm most >specifically considering Object.defineProperties, in the case when some >getter executed in the body of that loop (also in ToPropertyDescriptor) >results in a new property being added, a future property being removed, >a property being readded with the same name (does it attempt to define >the property twice?) -- all the usual enumeration hazards, but most >particularly the last one because of potential weirdness of defining the >same property twice with conflicting attributes between the two property >descriptors (if the appropriate behavior were specified to trigger >that). > >Jeff >_______________________________________________ >es-discuss mailing list >es-discuss@... >https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
RE: The precise meaning of "For each named own enumerable property name P of O"Oops, this wasn't really about for-in.
In Object.defineProperties should really be (inerted new step 3 and modified renumbered step 4: 1. If Type(O) is not Object throw a TypeError exception. 2. Let props be ToObject(Properties). 3. Let names be an internal list containing names of each enumerable own property of props 4. For element P of names in list order, a. Let descObj be the result of calling the [[Get]] internal method of props with P as the argument. b. Let desc be the result of calling ToPropertyDescriptor with descObj as the argument. c. Call the [[DefineOwnProperty]] internal method of O with arguments P, desc, and true. 5. Return O. If an implementation defines a specific order of enumeration for the for-in statement, that same enumeration order must be used to order the list in step 3 of this algorithm >-----Original Message----- >From: es-discuss-bounces@... [mailto:es-discuss- >bounces@...] On Behalf Of Allen Wirfs-Brock >Sent: Wednesday, August 12, 2009 2:34 PM >To: Jeff Walden; es-discuss@... >Subject: RE: The precise meaning of "For each named own enumerable >property name P of O" > >ES5 section 12.6 (for-in statement) says: > >The mechanics and order of enumerating the properties (step 6.a in the >first algorithm, step 7.a in the second) is not specified. Properties of >the object being enumerated may be deleted during enumeration. If a >property that has not yet been visited during enumeration is deleted, >then it will not be visited. If new properties are added to the object >being enumerated during enumeration, the newly added properties are >guaranteed not to be visited in the active enumeration. > >ES3 says pretty much the same thing with minor wording tweaks. > >>-----Original Message----- >>From: es-discuss-bounces@... [mailto:es-discuss- >>bounces@...] On Behalf Of Jeff Walden >>Sent: Wednesday, August 12, 2009 1:04 PM >>To: es-discuss@... >>Subject: The precise meaning of "For each named own enumerable property >>name P of O" >> >>What is the behavior when the body of the loop may have side effects? >>There are a number of these for the Object.* hooks, but I'm most >>specifically considering Object.defineProperties, in the case when some >>getter executed in the body of that loop (also in ToPropertyDescriptor) >>results in a new property being added, a future property being removed, >>a property being readded with the same name (does it attempt to define >>the property twice?) -- all the usual enumeration hazards, but most >>particularly the last one because of potential weirdness of defining >the >>same property twice with conflicting attributes between the two >property >>descriptors (if the appropriate behavior were specified to trigger >>that). >> >>Jeff >>_______________________________________________ >>es-discuss mailing list >>es-discuss@... >>https://mail.mozilla.org/listinfo/es-discuss > >_______________________________________________ >es-discuss mailing list >es-discuss@... >https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: The precise meaning of "For each named own enumerable property name P of O"On 12.8.09 14:33 , Allen Wirfs-Brock wrote:
> ES5 section 12.6 (for-in statement) says: That's specifically for the for-in statement in the language, not for a term of art used in other locations in the specification. If we want to adopt the definition, I think this should either be noted in 5.2 or described in some sort of prefatory statement in 15.2.3. Jeff _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: The precise meaning of "For each named own enumerable property name P of O"Oops, belay that, didn't see the followup email -- modifications in that email look fine.
Jeff _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: The precise meaning of "For each named own enumerable property name P of O"Allen Wirfs-Brock wrote:
> ES5 section 12.6 (for-in statement) says: > > The mechanics and order of enumerating the properties (step 6.a in the first algorithm, step 7.a in the second) is not specified. Properties of the object being enumerated may be deleted during enumeration. If a property that has not yet been visited during enumeration is deleted, then it will not be visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are guaranteed not to be visited in the active enumeration. > > ES3 says pretty much the same thing with minor wording tweaks. > I'm resurrecting this thread from August because I just noticed that one of the "minor wording tweaks" between the ES3 version and the ES5 version is this one: ES3: "the newly added properties are not guaranteed to be visited" ES5: "the newly added properties are guaranteed not to be visited" The transposition of the two words makes a big difference that doesn't seem like a minor tweak to me, and I can't find a discussion of it in the mailing lists so I wanted to make sure that this was an intentional rather than accidental change. David _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: The precise meaning of "For each named own enumerable property name P of O"On Fri, Oct 9, 2009 at 10:35 PM, David Flanagan <david@...> wrote:
It was intentional. It was discussed at least on the ES3.1 phone calls. Have you looked for a record at <http://wiki.ecmascript.org/doku.php?id=meetings:meetings>? -- Cheers, --MarkM _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: The precise meaning of "For each named own enumerable property name P of O"On Oct 9, 2009, at 10:35 PM, David Flanagan wrote:
> Allen Wirfs-Brock wrote: >> ES5 section 12.6 (for-in statement) says: >> The mechanics and order of enumerating the properties (step 6.a in >> the first algorithm, step 7.a in the second) is not specified. >> Properties of the object being enumerated may be deleted during >> enumeration. If a property that has not yet been visited during >> enumeration is deleted, then it will not be visited. If new >> properties are added to the object being enumerated during >> enumeration, the newly added properties are guaranteed not to be >> visited in the active enumeration. >> ES3 says pretty much the same thing with minor wording tweaks. > > I'm resurrecting this thread from August because I just noticed that > one of the "minor wording tweaks" between the ES3 version and the > ES5 version is this one: > > ES3: "the newly added properties are not guaranteed to be visited" > > ES5: "the newly added properties are guaranteed not to be visited" > > The transposition of the two words makes a big difference that > doesn't seem like a minor tweak to me, and I can't find a discussion > of it in the mailing lists so I wanted to make sure that this was an > intentional rather than accidental change. The spec is ambiguously worded here. Most (all?) implementations do not enumerate properties added to the directly referenced object after the loop has started, even though ES1-3 permitted this as implementation-dependent behavior: js> o = {p:1,q:2} ({p:1, q:2}) js> for (i in o) {o.r = 3; print(i)} p q js> However, prototype objects may gain properties after the loop has started and before the enumeration has reached the prototype in question, and so long as the added prototype property is not shadowed, it will be enumerated by some implementations (Mozilla's at least): js> function f(){} js> o = new f ({}) js> o.p = 1, o.q = 2 2 js> for (i in o) { f.prototype.r = 3; print(i); } p q r js> (HTML source you can test is here: http://pastebin.mozilla.org/675782 -- this particular pastebin page will stick around forever.) The spec's wording shifts subtly from "If new properties are added to the object being enumerated during enumeration, the newly added properties are guaranteed not to be visited in the active enumeration", which is arguably clear enough in context (adding properties to an object makes "own" properties in JS, and "*the* object being enumerated" seems to mean the object that was directly referenced by the result of evaluating the expression on the right of 'in'), to "[e]numerating the properties of an object includes enumerating properties of its prototype, and the prototype of the prototype, and so on, recursively [with shadowing]." So "added to the object" means both "own" properties and the directly- referenced object (evaluated from the expression on the right of 'in'), while "enumerating properties of an object" includes prototype properties if not shadowed. The old "hasOwnProperty" vs. "in" confusion bites here. The spec should be more precise, even if context makes the two usages clear enough for most readers. The upshot is that the last paragraph of 12.6.4 thus may be taken to say properties "of an object" include prototype properties, and therefore the earlier part about added properties may be taken to apply to added prototype properties too, specifying that they also are not enumerated. But in fact added prototype properties are enumerated by some implementations so long as the enumeration has not reached the prototype in question yet. Perhaps this is just something for those implementations to fix to conform to ES5, but let's discuss, since as David notes there's a lack of discussion on this point. To suppress prototype properties added after enumeration starts, the implementation must in effect take a snapshot of all the enumerable prototype property names as well as the direct names before the loop starts, instead of snapshotting the enumerable property names only of each object along the prototype chain as the loop progresses up the chain. In either case shadowing must be handled. Implementations using the "snapshot each object while traversing once" approach may see different shadowing effects than implementations that snapshot the whole chain up front and traverse again during the loop: function f(){} o = new f; o.p = 1, o.q = 2; f.prototype.r = 3; a = []; for (i in o) { o.r = 4; a.push(i); } alert('[' + a.join(', ') + ']'); (available at http://pastebin.mozilla.org/675804). This gives different results in different browsers although the result "[p, q]" shows what looks to me like a bug in Mozilla's SpiderMonkey implementation (I didn't test Rhino) where the late addition of o.r can shadow the prototype property. I'll file it. Another observation: using two traversals rather than one has higher inherent cost -- is this a consideration for the spec? I don't know, but at least it is guaranteed to visit the same objects on each traversal in the de-jure-standardized language. However, the writable __proto__ feature (a botch, my fault) is a de- facto standard, and it complicates things for implementations that support it. Do they traverse twice and risk the chain being mutated after the loop starts but before the loop's traversal (as opposed to the snapshotting one for all enumerable non-shadowed names)? The spec doesn't have to worry about this but some implementations do for now (Mozilla's, WebKit's). And even if there's no writable __proto__, if host objects can mutate [[Prototype]] then the possibility of inconsistent traversals arises. Since the spec is unclear and at least Mozilla's implementation does one traversal, and therefore shows added prototype properties so long as they are added after the loop starts but before the enumeration reaches the prototype in question, possibly this can remain an unspecified, implementation-dependent behavior -- for now. Or we can go with the ES5 change. But the trade-offs above need deliberate discussion. Comments welcome. /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: The precise meaning of "For each named own enumerable property name P of O"On Oct 10, 2009, at 1:09 PM, Brendan Eich wrote:
> In either case shadowing must be handled. Implementations using the > "snapshot each object while traversing once" approach may see > different shadowing effects than implementations that snapshot the > whole chain up front and traverse again during the loop: > > function f(){} > o = new f; > o.p = 1, o.q = 2; > f.prototype.r = 3; > a = []; > for (i in o) { > o.r = 4; > a.push(i); > } > alert('[' + a.join(', ') + ']'); > > (available at http://pastebin.mozilla.org/675804). This gives > different results in different browsers although the result "[p, q]" > shows what looks to me like a bug in Mozilla's SpiderMonkey > implementation (I didn't test Rhino) where the late addition of o.r > can shadow the prototype property. I'll file it. Filed at https://bugzilla.mozilla.org/show_bug.cgi?id=521617 /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
| Free embeddable forum powered by Nabble | Forum Help |