holes in spread elements/arguments
Sean Eagan
seaneagan1 at gmail.com
Fri Sep 30 06:41:57 PDT 2011
On Thu, Sep 29, 2011 at 2:53 PM, Allen Wirfs-Brock
<allen at wirfs-brock.com> wrote:
> It seems highly desirable that we preserve the existing semantics of arguments
I agree, for backward compatability.
> and that:
> function foo(...args) {
> assert(length.arguments === length.args};
> for (let i in arguments) assert(arguments.hasOwnProperty(i) ===
> args.hasOwnProperty(i) && arguments[i] === args[i]);
> }
I disagree, rest parameters are intended as an eventual permanent
replacement for `arguments`, and thus it is more important to make
them have the correct and consistent with array literal spread element
hole preservation behavior, than consistency with what will be the
legacy `arguments` to aid a one time migration to rest parameters. To
illustrate the problems I see with filling holes in rest parameters,
assume we are working with a holey array:
let holeyArray = [];
holeyArray[99] = true;
and some code which uses it:
let spreadTarget = [a, ...holeyArray, b]; // 99 holes
holeyArray.forEach(expensiveOperation); // 1 iteration
at some point we decide to abstract this code into functions:
function f(...arr) {
return [a, b, ...arr];
}
function g(...arr) {
arr.forEach(foo); // holes now filled leading to extra iterations
}
...
let spreadTarget = f(...holeyArray); // 99 unwanted `undefined`s now
g(...holeyArray); // 100 iterations now
> regardless of how foo was called. In other words, baz(...bar) and
> baz.apply(undefined,bar) should always produce the same effect.
I agree since one form is not intended to replace the other. The
effect IMHO should be that if baz uses `arguments`, holes are not
preserved for backward compatability, but if baz has upgraded to rest
parameters, then holes are preserved.
Also, I think not filling holes can be optimized since the `undefined`
values don't need to be added to the rest parameter argument.
Thanks,
Sean Eagan
More information about the es-discuss
mailing list