domenic at domenicdenicola.com (2013-08-25T00:56:43.765Z)
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?
```js
let p = {a: 1}
let o = {__proto__: p, [@@unscopeable]: ['a']}
let a = 2
with (o) {
a // 1 or 2?
}
let p = {[@@unscopeable]: ['a']}
let o = {__proto__: p, a: 1}
let a = 2
with (o) {
a // 1 or 2?
}
```
* How would it affect assignment?
```js
let o = {[@@unscopeable]: ['a']}
let a = 2
with (o) {
a = 1
a // 1 or 2?
o.a // 1 or undefined?
}
a // 1 or 2?
let p = {a: 1, [@@unscopeable]: ['a']}
let o = {__proto__: p}
let a = 2
with (o) {
a = 3
a // 1 or 2 or 3?
o.a // 1 or 3?
}
a // 2 or 3?
```
* How would it interact with mutation?
```js
let o = {a: 1}
let a = 2
with (o) {
o[@@unscopeable] = ['a']
a // 1 or 2?
}
```
* How would it interact with compound assignment?
```js
let o = {a: 1}
let a = 2
with (o) {
a += (o[@@unscopeable] = ['a'], 2)
a // 2 or 3 or 4?
o.a // 1 or 3?
}
a // 2 or 3 or 4?
```
* How would it affect the global object? (At least currently, with
scopes and the global scope share the same object environment
mechanism.)
```js
var a = 1
this[@@unscopeable] = ['a']
a // 1 or undefined?
var a
this[@@unscopeable] = ['a']
a = 1
a // 1 or undefined?
this[@@unscopeable] = ['a']
</script><script>
var a = 1
a // 1 or undefined?
```
* How would it expose side effects?
```js
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.
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? let p = {a: 1} let o = {__proto__: p, [@@unscopeable]: ['a']} let a = 2 with (o) { a // 1 or 2? } let p = {[@@unscopeable]: ['a']} let o = {__proto__: p, a: 1} let a = 2 with (o) { a // 1 or 2? } * How would it affect assignment? let o = {[@@unscopeable]: ['a']} let a = 2 with (o) { a = 1 a // 1 or 2? o.a // 1 or undefined? } a // 1 or 2? let p = {a: 1, [@@unscopeable]: ['a']} let o = {__proto__: p} let a = 2 with (o) { a = 3 a // 1 or 2 or 3? o.a // 1 or 3? } a // 2 or 3? * How would it interact with mutation? let o = {a: 1} let a = 2 with (o) { o[@@unscopeable] = ['a'] a // 1 or 2? } * How would it interact with compound assignment? let o = {a: 1} let a = 2 with (o) { a += (o[@@unscopeable] = ['a'], 2) a // 2 or 3 or 4? o.a // 1 or 3? } a // 2 or 3 or 4? * How would it affect the global object? (At least currently, with scopes and the global scope share the same object environment mechanism.) var a = 1 this[@@unscopeable] = ['a'] a // 1 or undefined? var a this[@@unscopeable] = ['a'] a = 1 a // 1 or undefined? this[@@unscopeable] = ['a'] </script><script> var a = 1 a // 1 or undefined? * How would it expose side effects? 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. /Andreas