undefined being treated as a missing optional argument

David Herman dherman at mozilla.com
Fri Apr 13 12:17:58 PDT 2012

On Apr 13, 2012, at 12:05 PM, Oliver Hunt wrote:

> On Apr 13, 2012, at 11:48 AM, David Herman <dherman at mozilla.com> wrote:
>> On Apr 13, 2012, at 11:35 AM, Oliver Hunt wrote:
>>> foo(undefined);
>> 1, 2, 1
> Uh what? I pass no arguments and arguments.length is 2, and i pass one argument and arguments.length is 1?

See my follow-up, answer to the first one was wrong; arguments.length is of course 0 in the first case.

>>> foo(undefined, undefined);
>> 1, 2, 2
> So i've passed 2 arguments, but they both get replaced?


>>> foo(undefined, 3);
>> 1, 3, 2
> So if you have default values we have to emit code to check for undefined in each case?
> is foo(a=5, b) valid?  The above examples imply that it should be.

I'm somewhat ambivalent about it. Sure, it's true that "undefined always gets replaced by default" means it's possible to get a defaulted argument followed by a non-defaulted argument. But we also don't have to encourage writing positional arguments like that; they can use options objects for that.

>>> foo(3, undefined);
>> 3, 2, 2
>>> Default values are for when arguments are not passed,
>> Stated without evidence!
> C++, python, ...

That's precedent, but not an actual argument about *why* it should be done one way or another. (Also, the decision is utterly different in a statically typed language, so C++ isn't relevant.)

> This makes it impossible for me to distinguish between passing undefined as an argument and not passing an argument.

That's right. In that case, you should not use the x=expr default syntax. But this is an uncommon case. The semantics you advocate is optimizing for the wrong cases.

> If i've written:
> foo(undefined)
> There's a very clear expectation that i have selected undefined as the value i want to be passed.

You can just as easily say that if you've written:


there's a very clear expectation that if getOptionalValue() returns undefined, you don't want the value to be passed.

> Yet you're saying this should be interpreted as foo() (only with a shorter arguments.length).

Longer argument.length, but yes.


More information about the es-discuss mailing list