Assume we have a function, which expects three parameters that have to be added, then returned as a sum. It can be defined this way:
Now, assume that the second parameter should have default value equal to 0, and the last one – equal to 2. In ES6 we would write:
But usually we cannot use ES6 and we have to manually check if the parameter has a value provided. You can find a few different ways to do that. One of them, and the simplest one, is to use the OR operator which works on any type, not only on boolean values:
The trick with this approach is that the OR operator returns the first operand if it’s a truthy value, otherwise it returns the second one. So this code won’t work if we want to provide 0 as a third parameter. The same goes for any falsy value, such as: 0, NaN, "" (empty string), null, and undefined. (BTW. every truthy/falsy value can be converted to true/false value using double ‘!’ operator, e.g. !!NaN === false, !! === true.)
The next and very common approach is to check if the parameter is undefined, i.e.:
You can check for undefined value either by comparing with it (like for b parameter), or by checking if its type is ‘undefined’ (like for the c parameter). This way works in virtually every case but one… what if someone has to detect if the undefined value was passed deliberately? (Yes, it’s weird, I know.) In this case, we can check the length of a special array named arguments, i.e.:
Unfortunately, this approach has a few disadvantages. Using the arguments array, and reassigning the parameter value causes the function to be non-optimizable in Firefox and Chrome. There is a workaround, though. You can enable strict mode and save the values in local variables, which enables optimization again. Surprisingly, strict mode causes the code to run much slower in Microsoft browsers.
I’ve prepared the code, which tests the speed of each solution on a few popular browsers, the results are in the following table. (You can see the code, and perform the test by yourself here: http://js.do/LukeSw/obj_defaultparameters.)
|Arguments check (strict mode)||14936.2||9023.9||2137.1||126.3|
|Arguments check (local variable)||6258.2||2787.1||139.9||191.0|
|Arguments check (both)||14955.4||8959.9||139.9||127.2|
* time in ms
As you can see, the most common approaches are the fastest ones. Using arguments array causes the code to run few times slower. This can be optimized by saving parameters’ values in local variables and/or by enabling strict mode (depends on the browser).
So, which way should be used? Well, that depends on requirements. If the default value is falsy, then using OR operator will suffice. It’s the fastest (or almost the fastest) solution in every browser, and it’s the simplest one.
If the default value has to be a truthy value, the best approach is to explicitly check for undefined value or type, and as you can see, neither solution from these two is better/faster than the other one. So you can use the shorter version.
Should you ever need to use arguments array, please always remember about the optimization. Saving parameters (which need to be reassigned) in local variables cause the code to run faster in every browser. If you have to use the strict mode, bear in mind that it causes the code to run much slower in MSIE and Edge.
For more information on this subject, please follow the links: