Override JavaScript default parameter with undefined

Viewed 4178

I have a function with argument bar that has a default parameter, "". How do I override bar's default parameter with value undefined?

const foo = (bar = "") => {
  console.log(bar)
}

foo(null) // null
foo(undefined) // "" <-- I want this to log `undefined`

If this is impossible with default parameters, what would be an appropriate way to write foo to achieve this?

6 Answers

what would be an appropriate way to write foo to achieve this?

If you mean to default only when there is no parameter passed to the function call, then you need to check the arguments length, or to spread the arguments if you want to keep an arrow function.

const foo = (...args) => {
  const bar = args.length ? args[0] : "";
  console.log(bar)
}

foo(null) // null
foo(undefined) // undefined
foo(); // ""

No, you can't, by design.

You've run into an interesting demonstration of JavaScript's 'two nulls', null and undefined.

null is a designated null value

undefined is the absence of any value at all

You ask about the passing the 'value' undefined but that premise is flawed. There is no value undefined - undefined is the lack of a value.

Therefore, you shouldn't pass undefined as a meaningful value to be interpreted by a function. I mean, you can, but from the point of view of JavaScript it is equivalent to passing nothing at all - so you're fighting against the design of the language and will run into issues like this one.

If you want to pass a meaningful, purposeful null value, that is what null is for.

Maybe because you can't. That's the reason default parameters are designed to guard against undefined values.

As per Mozilla documentation

Default function parameters allow named parameters to be initialized with default values if no value or undefined is passed

See above. It's clearly written: if undefined is passed, default parameters are used.

In the example code you just provided, that's apparently not possible.

As per the official documentation.

In JavaScript, function parameters default to undefined. However, it's often useful to set a different default value. This is where default parameters can help.

The very definition of default parameters is to initialize no values or undefined with the given values.

So, you would want to remove the default parameter and add a conditional check within your function(see Kaiido's answer). Otherwise, you cannot differentiate between foo(undefined) and foo().

If you want both foo(undefined) and foo() to log undefined, you can simply remove the default parameter

Given this method (typescript, sorry I assume es6 is similar):

private static Foo(test: string, bar?: string): void
{
    let args = arguments && arguments.length ? arguments.length : 0;

    console.log(test, {
        bar: bar,
        type: typeof bar,
        isUndefined: bar === undefined,
        arguments: args,
        value: (bar === undefined && args == 2) ? undefined : (bar === null && args == 2) ? null : bar ? bar : ""
    });
}

Called with this:

let u;
let v = undefined;

this.Foo("no parameter");
this.Foo("null", null);
this.Foo("empty", "");
this.Foo("non-empty", "non-empty");
this.Foo("undefined", undefined);
this.Foo("undefined parameter", u);
this.Foo("parameter with value of undefined", v);

We get these results:

no parameter 
{bar: undefined, type: "undefined", isUndefined: true, arguments: 1, value: ""}

null 
{bar: null, type: "object", isUndefined: false, arguments: 2, value: null}

empty 
{bar: "", type: "string", isUndefined: false, arguments: 2, value: ""}

non-empty 
{bar: "non-empty", type: "string", isUndefined: false, arguments: 2, value: "non-empty"}

undefined 
{bar: undefined, type: "undefined", isUndefined: true, arguments: 2, value: undefined}

undefined parameter 
{bar: undefined, type: "undefined", isUndefined: true, arguments: 2, value: undefined}

parameter with value of undefined 
{bar: undefined, type: "undefined", isUndefined: true, arguments: 2, value: undefined}

Thus we can see that we cannot tell the difference between a variable that is undefined and a variable that contains the value undefined.

By looking at the number of arguments we can tell if an argument is missing, and then if it is exactly (===) undefined or null.

Related