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 <g...@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@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss