For more tips like this, sign up to the weekly newsletter!

When default parameters differ from manual initialization

Default parameters in Javascript are used to make use of a conditional set. For a simple adder function:

const f = (a, b) => {
    return a + b;
}

To make b optional and set it to a default if it is not provided can be done in several ways.

The shorter form is b = b || 5, but that sets b to 5 for all falsy values, which includes null, 0, "", and a few other edge cases.

A better solution is to check for undefined: b = b === undefined ? 5 : b. (A slightly more robust solution is to use void 0 instead of undefined)

Since ES2015, functions can define defaults, which makes the syntax more concise:

const f = (a, b = 5) => {
    return a + b;
}

This construct seems identical to the above check, but it behaves differently in at least one aspect.

Function.length

The function.length returns the number of required arguments of a function. In the first case, this is 2:

const f = (a, b) => {
    b = b === undefined ? 5 : b;

    return a + b;
}

console.log(f.length); // 2

In contrast, setting the default in the function declaration makes the function require one less argument:

const f = (a, b = 5) => {
    return a + b;
}

console.log(f.length); // 1

Usually, it's not a problem as hardly any code relies on the number of arguments. But for example, in the case of memoization, the cache can be made faster by taking account the number of parameters, like memoizee does. But in this case, the second argument will be ignored, resulting in stale cache.

Manually checking for undefined provides the correct result:

const f = (a, b) => {
    b = b === undefined ? 5 : b;

    return a + b;
}

const memoized = memoizee(f);

console.log(memoized(3)); // 3 + 5 = 8
console.log(memoized(3, 4)); // 3 + 4 = 7

While using default parameters makes memoization ignore the second argument, producing an incorrect result:

const f = (a, b = 5) => {
    return a + b;
}

const memoized = memoizee(f);

console.log(memoized(3)); // 3 + 5 = 8
console.log(memoized(3, 4)); // 8 !!!!
Try it
References
Learn more: