12.14.5.3 Runtime Semantics: IteratorDestructuringAssignmentEvaluation
Production:
AssignmentElement[Yield] : DestructuringAssignmentTarget Initializer_opt
The evaluation order for this production is not consistent with the evaluation order for other destructuring assignment or destructuring binding productions.
Test case:
---
(function() {
var a, b, c;
var o = {};
with (o) {
([a] = function*(){ o.a = 0; yield 1; }());
([...b] = function*(){ o.b = 0; yield 1; }());
({c} = {get c(){ o.c = 0; return 1 }});
}
print(`a = ${a}, o.a = ${o.a}`);
print(`b = ${b}, o.b = ${o.b}`);
print(`c = ${c}, o.c = ${o.c}`);
})();
(function() {
var o = {};
with (o) {
var [A] = function*(){ o.A = 0; yield 1; }();
var [...B] = function*(){ o.B = 0; yield 1; }();
var {C} = {get C(){ o.C = 0; return 1 }};
}
print(`A = ${A}, o.A = ${o.A}`);
print(`B = ${B}, o.B = ${o.B}`);
print(`C = ${C}, o.C = ${o.C}`);
})();
---
Output with current semantics:
---
a = 1, o.a = 0
b = undefined, o.b = 1
c = undefined, o.c = 1
A = undefined, o.A = 1
B = undefined, o.B = 1
C = undefined, o.C = 1
---
and unfortunately, the odd man out, in this case, appears to be correct and all the others appear incorrect.
In general, we are supposed to do left-to-right evaluation for assignment/binding initialization unless the target is a destructing object/array. In all these cases, the target is a simple identifier binding so it should be resolved before fetching the value (nexting the iterator, accessing the property, etc.) so they should all resolve the assignment/binding target to the outer variable rather than the property of the with object.
This is going to take some thought to fix.
fixed in rev30 editor's draft
fixed in rev30