Some answers inline. On Wed, Aug 21, 2013 at 7:58 AM, Andreas Rossberg <rossb...@google.com> wrote: > I'm still trying to wrap my head around the idea of introducing an > @@unscopeable property, as discussed at the last meeting. There seem > to be plenty of edge cases: > > * How would it interact with inheritance?
with always uses the full prototype chain. @@unscopable is gotten using a [[Get]] so the whole prototype chain is considered. > let p = {a: 1} > let o = {__proto__: p, [@@unscopeable]: ['a']} > let a = 2 > with (o) { > a // 1 or 2? > } 2, 'a' is blacklisted from being part of the object environment record. > let p = {[@@unscopeable]: ['a']} > let o = {__proto__: p, a: 1} > let a = 2 > with (o) { > a // 1 or 2? > } 2, for the same reason > * How would it affect assignment? This is one of the details we didn't talk about, but the concept is that 'a' is not part of the object environment record, so free a means the lexical a (if any). One way to think of it is that the with is acting on a view of the object that does not have the blacklisted properties. This can be implemented using proxies. I'll leave that as an exercise. > let o = {[@@unscopeable]: ['a']} > let a = 2 > with (o) { > a = 1 > a // 1 or 2? 1 > o.a // 1 or undefined? undefined > } > a // 1 or 2? 1 > let p = {a: 1, [@@unscopeable]: ['a']} > let o = {__proto__: p} > let a = 2 > with (o) { > a = 3 > a // 1 or 2 or 3? 3 > o.a // 1 or 3? 1 > } > a // 2 or 3? 3 > * How would it interact with mutation? Another hole we didn't cover. Here is my proposal: The @@unscopable is only accessed once, when the object environment record is created. > let o = {a: 1} > let a = 2 > with (o) { > o[@@unscopeable] = ['a'] > a // 1 or 2? 1, @@unscopable was set too late. > } > > * How would it interact with compound assignment? this one falls out of the previous one. > let o = {a: 1} > let a = 2 > with (o) { > a += (o[@@unscopeable] = ['a'], 2) > a // 2 or 3 or 4? 3 > o.a // 1 or 3? 3 > } > a // 2 or 3 or 4? 2 > * How would it affect the global object? (At least currently, with > scopes and the global scope share the same object environment > mechanism.) The idea was that it would be part of with only. We don't want to tax the global property lookups for this. > var a = 1 > this[@@unscopeable] = ['a'] > a // 1 or undefined? 1 > var a > this[@@unscopeable] = ['a'] > a = 1 > a // 1 or undefined? 1 > this[@@unscopeable] = ['a'] > </script><script> > var a = 1 > a // 1 or undefined? 1 > * How would it expose side effects? It does a [[Get]] in the with head. > let s = "" > let o = {a: 1} > let u = {get '0'() { s+="0"; return 'a' }, get '1'() { s+="1"; return 'b' }} > Object.defineProperty(o, @@unscopeable, {get: function() { s += "u"; > return u }}) > > with (o) {} > s // "" or "u" or "u01" or ...? > > with (o) { c; c } > s // "u01" or "u01u01" or ...? > > with (o) { a } > s // "u01" or "u0" or ...? > > with (o) { a+=1 } > s // "u0" or "u00" or "u01" or "u0101" or ...? > > Some of this looks rather whacky, if not unpleasant. If you think of it as only doing it once in the with head things become much simpler to understand. -- erik _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss