Clarification on function default param values

Dmitry Soshnikov dmitry.soshnikov at gmail.com
Tue Oct 1 13:29:29 PDT 2013


On Mon, Sep 30, 2013 at 8:21 PM, Brandon Benvie <bbenvie at mozilla.com> wrote:

> On 9/30/2013 3:51 PM, Dmitry Soshnikov wrote:
>
>> Just re-read meeting notes, OK, cool on two scopes (seems like they are
>> not in the spec yet). Want to double-check though: whether it will be
>> possible to transpile now to ES3? From what I've seen in the notes, the
>> head-scope will be able to access `this` value of the activation, etc. Not
>> sure how to transpile now. Could someone give an example of a wrapper scope
>> please, and confirm whether it's transpilable now?
>>
>
> I believe it is transpilable if you use an inner function scope. Someone
> correct me if my translations are semantically incorrect:
>
>
> ES6:
> ```js
> var x = 1, y = 2;
> function foo(x = 3, y = y, z = y) {
>   return [x, y, z];
> }
> ```
>
> ES3:
> ```js
> var x = 1, y = 2;
> function foo(x, y, z) {
>   // defaults
>   if (x === undefined) {
>     x = 3;
>   }
>   if (y === undefined) {
>     y = y; // essentially a no-op
>   }
>   if (z === undefined) {
>     z = y;
>   }
>
>   // body
>   return (function(x, y, z){
>     return [x, y, z];
>   }).call(this, x, y, z);
> }
> ```
>
>
OK. Thanks for the example. There are some edge cases with transpiling to
ES3, e.g. if the inner function mutates the arguments.callee by attaching a
new property to it, or something (the property is attached to the inner
function then, not to the outer wrapper). But transpiling cases shouldn't
stop the actual spec for engines of course.

Also, what about using other parameter transforms in conjunction, e.g. rest
parameters and destructuring: are they duplicated in the signature of the
inner function, is their coded are injected into the inner function or to
the outer one?



>
>
> A clearer example of my own which I think demonstrates the scoping better
> (or exposes a problem with my understanding):
>
> ES6
> ```js
> function foo(x, y = function() { return x }) {
>   x++;
>   return x + y();
> }
>
> foo(1); // is this 3 or 4?
> ```
>
> ES3:
> ```js
> function foo(x, y) {
>   // defaults
>   if (y === undefined) {
>     y = function() { return x };
>   }
>
>   // body
>   return (function(x, y) {
>     x++;
>     return x + y();
>   }).call(this, x, y);
> }
>
> foo(1); // 3
> ```
>


Yeah, this one is debatable though. I think it's either, or. Both variants
can be correct, depending on how it's speced. If it's spected that the
defaults are evaluated in the function scope, then it shouldn't be a
surprise that the if can be 4 (and in this case we probably don't need two
scopes. Wondering, can all the edge cases be covered by the single sentence
in the spec: "All default values are evaluated in the scope of a function"?
Or those edge cases are too not-obvious from the programmers perspectives?).

Dmitry
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131001/c882ca13/attachment-0001.html>


More information about the es-discuss mailing list