
Don't use || to set default values in JavaScript - mostlystatic
http://www.codereadability.com/javascript-default-parameters-with-or-operator/
======
hobozilla
"The OR adds mental overhead for whoever works on the function in the future"

What world is this guy living in? It's like it's the first time he's seen this
and just decided "I don't like it, let me write an article about that".

Anyone working in JS for more than a month will have seen this as common
practice. It much neater (and less mental headspace IMHO) than an extra if
block. Particularly if you have more than one optional variable.

The only practical consideration raised is the falsy types can trip you up but
that is easily negated. I have strong negative feelings for people who impose
their own personal believes based on nothing but their feelings.

~~~
pweissbrod
Agreed. His statement is based on opinion, nothing objective. I could argue
that in languages like C# the coalesce operator '??' has a similar meaning, so
it is intuitive for people who know C# concepts.

~~~
MichaelGG
C#'s coalese only works on null. The problem is that JS will apparently see an
empty string or 0, and consider that null. So if your function passes those
values deliberately, the || trick breaks.

So long you're OK with that, it seems like a clean solution. It's JavaScript.
There's tons of dumb stuff a JS coder must learn. If he's confused by || then
he's likely to be unable to work on any real JS.

------
rdancer
Bullshit. Using _foo = bar || baz_ is perfectly valid when used judiciously.

 _foo = bar || baz_ is perfect when parsing inputs where unset is passed as ""
or 0. To no great surprise, HTML forms are one such beast.

The Boolean operators are simply a shorthand for _if (!foo) foo = bar_ \--
when you mean _if (foo === undefined) foo = bar;_ then simply write that
instead. At least omit the unnecessary braces and white space.

Verbose code is not necessarily more readable. You may be able to code your
way around a reader not comprehending JS rules regarding Boolean coercion, but
those rules are based on real world inputs which often do not have a special
'undefined' value.

~~~
tracker1
I came in here to write pretty much the same thing... the only issue for me
tends to be when 0 is allowed. As an interview problem, I will ask someone to
write in JavaScript a method that takes a single parameter, that will always
return a number or null.. if it's a string that represents a number, convert
it, otherwise it should be null.

0 always trips people up in this, or other means of coercion. Other than that
one case, I find the shortcut of || to be pretty much invaluable.

This is an example of something you should just learn how it works, rather
then assume it's stupid or wrong because you don't know how the environment
works. You should have seen how many people went up in arms at LINQ and even
Lambda functions in C#. I've seen similar comments about lambda/fat-arrow
functions coming into JS.

~~~
acjohnson55
Is that a great interview question? It strikes me as the sort of thing where a
positive doesn't tell you all that much additional about someone's engineering
ability, nor does a negative.

~~~
tracker1
It isn't the only thing I judge on, but when you see a stack of resumes where
people put their JavaScript knowledge as "expert" ... I expect it to be a
relatively easy question. It comes down to a level of honesty, and when
someone says they are an expert with a language, they better know that
language pretty well.

Like "what are the falsy values in JavaScript" (I usually let people get away
with 3+ of them)

In the browser a very primary purpose for JavaScript is input validation...
this includes strings... being able to reuse a method for internal validation
is useful as well. Knowing how to do something useful in a language is a
perfectly fine interview question.

It isn't like I'm asking people to write a bubble-sort, or how an IEEE 754
number is structured and how that relates to JS... Or how to determine the
number of marbles in a given jar... or any other of other questions I've been
asked in an interview. I'm asking someone to validate a simple input in one of
the most widely used programming languages on the planet.

Sorry to go on a rant.. but hiring is hard, and when you are looking at
someone why says they have a lot of experience with the skills that you are
looking for (full-stack javascript/node)... expectations shouldn't be too low.

I'm more than happy to talk to people with other backgrounds and skills...
I've hired plenty of newer/eager learners who don't have a lot of experience,
but demonstrated the ability to work through a problem. In my mind
effort/ambition/trying-stuff means more than specific experience.

------
Mithaldu
Perl solved that issue by introducing the // and //= operators, which do the
same thing as || and ||=, but restricted to consider only undef as false.

~~~
J_Darnley
You mean those are not integer divide operators?

~~~
Mithaldu
Numbers are float by default in Perl. If you want Integer operations you need
to cast with int() or use
[https://metacpan.org/pod/integer](https://metacpan.org/pod/integer)

------
chrisdew

        var undefined = "raspberry";
    
        function eatFruit (fruit) {
            if (fruit === undefined) {
                fruit = "strawberry";
            }
            ...
        }
    
        eatFruit("raspberry");

~~~
kcorbitt
I was intrigued and just tried this. It doesn't work (at least in the chrome
console) -- "undefined" is a reserved keyword and while the interpreter
doesn't complain about attempting to assign it the value of "raspberry," it
appears to ignore the statement.

~~~
chrisdew
Apologies, you're right.

I'm sure this used to work, a few years ago... but I may be getting old.

~~~
chrisdew
But there's definitely still odd stuff here:

    
    
        $ node  
        > var bar = undefined = "foo";
        undefined
        > bar
        'foo'
        > undefined
        undefined
        >

------
ricklancee
Shouldn't the undefined check be like this?

    
    
        if (typeof fruit === "undefined") {
           fruit = "strawberry";
        }
    

Unless your doing something like:

    
    
        (function(undefined) {
    
        })();

~~~
kevincennis
In ES5+, the global `undefined` is immutable, so it should be pretty safe
unless someone declared a local `undefined` var in an outer scope.

~~~
arnehormann
I use "var undef;" at the top of a function and never set it to a value.
Comparison with === is the same as with undefined. And it's nice for
minification.

------
nevi-me
Similar to what everyone else is saying, I don't get the author's point. I
taught myself JavaScript a few years ago, and the first time I came across
that || assignment, it made sense. I think many other people would say the
same.

------
kevincennis
I agree that default parameters will be a much nicer solution to this problem,
but using the OR operator is a very common practice in JS, and any dev with
more than about 5 weeks experience will recognize and understand that pattern
pretty much automatically.

In the example with the undefined check... what if undefined is a valid
argument? You should actually check the length of the arguments object.

See, you can always find examples of when you shouldn't do something. That
doesn't mean you shouldn't EVER do it. At the end of the day, people who read
and write code need to understand how it works. You can only protect people
from themselves so much.

------
PythonicAlpha
It is similar as in C:

When C come out, it did not include a bool type, since it could be easily
implemented as integer or char. The result was, that every bigger project had
its own standard of the boolean type. This lead to the situation that bringing
together different libraries or projects in the same company, you very soon
had four or more different (and potential incompatible) boolean types with
different constants for TRUE, FALSE, true, false and UNDEFINED. The
programmers where happy to deal with those ...

It would be best (and fastest) to include something like default parameters
into the language much sooner ...

But at least in this case, I see much less trouble as with the C type and I do
not agree with the author that there is mental overhead involved with the OR
operator, since you normally get used to it fast.

------
smhg
I don't agree either.

The first part of the argumentation is indeed based on the author's feelings.
The second part I don't think is an issue for most real world use-cases
(Objects, Strings and, to a lesser extent, Numbers).

On the underscore (_.defaults) recommendation: let's set our goals straight
[1]. Aim for a good level of JavaScript understanding. Instead of library
knowledge to make up for the lack of the former.

[1]
[https://www.youtube.com/watch?v=4anAwXYqLG8](https://www.youtube.com/watch?v=4anAwXYqLG8)

------
zongitsrinzler
I don't agree. Replacing all occurrences of default values that use || with a
3 rows long if case would hurt readability.

There are many valid cases where the incoming parameter could be either
undefined or null.

------
vilmosi
>>> First of all, it isn’t obvious why the OR operator would be used to assign
default values.

Really?! This is common knowledge for anyone writing JS for more than a week.
It's used EVERYWHERE.

------
CmonDev
Doesn't it also check for _null_ not just _undefined_? Isn't that the whole
point?

~~~
tracker1
Any truthy value will be returned and short out the boolean expression.. falsy
values fall through...

falsy values are: "", 0, null, undefined, NaN and false

Everything else is truthy.

I kind of wish that Invalid Date (invalidDt.valueOf() === NaN), empty arrays,
and objects without any properties were also falsy sometimes. Though I also
wish that sometimes 0 was easier to separate from other falsy values.

------
Ensorceled
I look for more such insightful articles from
[http://www.codereadability.com/](http://www.codereadability.com/) in the
future. /s

------
xsace
var skill;

article = skill || 'troll'

------
deckar01
I was always instructed to use typeof when determining if a variable or
property is undefined. Some attempts to access an undefined variable will
result in an exception being thrown.

[http://stackoverflow.com/questions/27509/detecting-an-
undefi...](http://stackoverflow.com/questions/27509/detecting-an-undefined-
object-property)

~~~
masklinn
That's only a serious issue if the binding may not exist at all, which is an
other way to say that it's only useful for global variables. A function
parameter defines a binding by definition.

~~~
deckar01
Good to know. I peeked into underscore's source to see how this type of check
is handled.

Aparently the issue is more complicated than I thought, because the following
comparison is used:

obj[key] === void 0

Are they really defending themselves against the function being rebound with
undefined shadowed?

[http://adripofjavascript.com/blog/drips/javascripts-void-
ope...](http://adripofjavascript.com/blog/drips/javascripts-void-
operator.html)

~~~
masklinn
Yeah. It might be an issue when you're a widely used library, you might
routinely encounter completely insane stuff. In a codebase you own though, I
wouldn't worry about it, you can just set whoever decides rebinding undefined
is funny on fire.

------
bsimpson
tl;dr: use Babel to get default arguments that are both more readable and more
robust, along with a bunch of other JS Harmony improvements, for free.

~~~
aikah
> tl;dr: use Babel to get default arguments that are both more readable and
> more robust, along with a bunch of other JS Harmony improvements, for free.

You mean replace perfectly valid javascript with a complicated nodejs pipeline
in order to make scripts run in the browser now? hell no.

~~~
tracker1
I like babel for plenty of other reasons... the single biggest one is the
culmination of Promise + coroutines with async/await keywords.

Not to mention being able to break code into discrete modules that can be
utilized without having to jump through namespace hoops or global collisions
(does $ mean jQuery, Prototype, document.querySelectorAll, ...).

------
mromanuk
Thanks, but no. I will use ||

------
domainkiller
fruit = (fruit === undefined) ? "strawberry" : fruit

