"for-in", shadowing and deleting properties.

Andreas Rossberg rossberg at google.com
Thu May 9 04:58:29 PDT 2013


Hi Gareth,

mostly for historic reasons, for-in is one of the darkest corners of
the ES spec. It is intentionally vague, because existing
implementations differ widely in their handling of this construct.

To address your question: the spec simply does not prescribe anything
coherent for this case. Have you tried different implementations? I
assume they will differ, and consequently, there likely is little
chance to tighten the spec for this case, nor to agree on a suitable
test case for test262. It's long been acknowledged that for-in is
beyond repair, which is why ES6 will have for-of as a more
well-behaved replacement.

Nevertheless, it's probably worth filing a bug against the spec
(https://bugs.ecmascript.org/describecomponents.cgi?product=ECMA-262).
It could at least make clear that nothing is clear for this case. :)
And yes, I can see how that sucks for JSCert.

As for your other question, yeah, I think that "property" and
"property with name" are used interchangeably in those parts of the
spec.

/Andreas


On 8 May 2013 20:16, Gareth Smith <gds at doc.ic.ac.uk> wrote:
> Hello,
>
> I hope this is the right place to ask this question - please let me know
> if not!
>
> I am trying to understand the specification of for-in, both for ES5 and
> for ES6, and in particular the interaction between shadowing and adding
> or deleting properties. Here are the parts of the ES5 spec and ES6 draft
> that seem most relevant:
>
> ES5: http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4
> ES6: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-8.3.12
>
> Here are two motivating examples. In both examples, I'll assume that 'y'
> is enumerated first. For each example, the question is: does the
> specification require 'x' to be enumerated, or can an implementation
> choose to skip it?
>
> Example 1:
>
> var b = { x : 2 }
> var a = { y : 0, __proto__ : b }
>
> for (i in a){
>     console.log(i + ": " + a[i]);
>     a.x = 1
> }
>
> In this first example b.x becomes shadowed by a.x before being
> enumerated. Thus we have both "If new properties are added to the object
> being enumerated during enumeration, the newly added properties are not
> guaranteed to be visited in the active enumeration" and "a property of a
> prototype is not enumerated if it is “shadowed” because some previous
> object in the prototype chain has a property with the same name."
>
> Does the specification allow us to skip 'x'?
>
> Example 2:
>
> var b = { x : 2 }
> var a = { y : 0, x : 1, __proto__ : b }
>
> for (i in a){
>     console.log(i + ": " + a[i]);
>     delete(a.x)
> }
>
> In this second example, a.x is deleted before it is visited. Thus,
> following "If a property that has not yet been visited during
> enumeration is deleted, then it will not be visited", it should not be
> visited. The b.x property is no longer shadowed, but it was not supposed
> to be enumerated in the first place. So can it be skipped?
>
> An alternative reading of the specification is that we are interested in
> property /names/, not properties. Given this reading, in both examples a
> property named 'x' was always reachable from a, so it must be enumerated
> in both examples. Is this second reading closer to the intent of the
> specification? I note that the current wording of the spec talks about
> "properties" when things are being added and deleted, and "property
> names" only when talking about duplicate enumerations.
>
> Thanks a lot!
>
> Gareth.
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss


More information about the es-discuss mailing list