"for-in", shadowing and deleting properties.

Andrea Giammarchi andrea.giammarchi at gmail.com
Wed May 8 13:54:42 PDT 2013


in the Example 1 you simply loop over all keys in the chain, included the x
inherited from b.

The fact you shadow that is irrelevant, it was there in any case.
The fact you get 1 in the log is because you access the shadowed property
through a[i] so expected result.

You are doing a for/in, not a for/of

In the second Example is the same, for/in loops over all enumerable
properties in the chain, it does not matter what you do with the current
instance if that property name is inherited so, once again, expected.

var b = { x : 2 },
    a = { y : 0, __proto__ : b },
    k;

for (k in a){
    alert(k + ": " + a[k]);
    delete b.x; // note: it's b, not a
}

this will loop only over a.y skipping x

If you want to be sure about having a keys snapshot of the own properties,
you can, in ES6:

let b = {x: 2},
    a = {y: 0, __proto__: b},
    k;

for (k of Object.keys(a)) {
  console.log(k);
}

or an equivalent for loop/iteration over keys such

Object.keys(a).forEach(function(k){
  this[k]; // whatever
}, a);

br



On Wed, May 8, 2013 at 11:16 AM, 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130508/39802553/attachment.html>


More information about the es-discuss mailing list