I am debugging some JavaScript, and can't explain what this ||
does?
function (title, msg) {
var title = title || 'Error';
var msg = msg || 'Error on Request';
}
Can someone give me an hint, why this guy is using var title = title || 'ERROR'
? I sometimes see it without a var
declaration as well.
Double pipe stands for logical "OR". This is not really the case when the "parameter not set", since strictly in the javascript if you have code like this:
Then calls
are not equivalent.
Double pipe (||) will cast the first argument to boolean and if resulting boolean is true - do the assignment otherwise it will assign the right part.
This matters if you check for unset parameter.
Let's say, we have a function setSalary that has one optional parameter. If user does not supply the parameter then the default value of 10 should be used.
if you do the check like this:
This will give unexpected result on call like
It will still set the 10 following the flow described above.
Explaining this a little more...
The
||
operator is the logical-or
operator. The result is true if the first part is true and it is true if the second part is true and it is true if both parts are true. For clarity, here it is in a table:Now notice something here? If
X
is true, the result is always true. So if we know thatX
is true we don't have to checkY
at all. Many languages thus implement "short circuit" evaluators for logical-or
(and logical-and
coming from the other direction). They check the first element and if that's true they don't bother checking the second at all. The result (in logical terms) is the same, but in terms of execution there's potentially a huge difference if the second element is expensive to calculate.So what does this have to do with your example?
Let's look at that. The
title
element is passed in to your function. In JavaScript if you don't pass in a parameter, it defaults to a null value. Also in JavaScript if your variable is a null value it is considered to be false by the logical operators. So if this function is called with a title given, it is a non-false value and thus assigned to the local variable. If, however, it is not given a value, it is a null value and thus false. The logical-or
operator then evaluates the second expression and returns 'Error' instead. So now the local variable is given the value 'Error'.This works because of the implementation of logical expressions in JavaScript. It doesn't return a proper boolean value (
true
orfalse
) but instead returns the value it was given under some rules as to what's considered equivalent totrue
and what's considered equivalent tofalse
. Look up your JavaScript reference to learn what JavaScript considers to be true or false in boolean contexts.What is the double pipe operator (
||
)?The double pipe operator (
||
) is the logicalOR
operator . In most languages it works the following way:false
, it checks the second value. If it'strue
, it returnstrue
and if it'sfalse
, it returnsfalse
.true
, it always returnstrue
, no matter what the second value is.So basically it works like this function:
If you still don't understand, look at this table:
In other words, it's only false when both values are false.
How is it different in JavaScript?
JavaScript is a bit different, because it's a loosely typed language. In this case it means that you can use
||
operator with values that are not booleans. Though it makes no sense, you can use this operator with for example a function and an object:What happens there?
If values are not boolean, JavaScript makes implicit conversation to boolean. It means that if the value is falsey (e.g.
0
,""
,null
,undefined
(see also All falsey values in JavaScript)), it will be treated asfalse
; otherwise it's treated astrue
.So the above example should give
true
, because empty function is truthy. Well, it doesn't. It returns the empty function. That's because JavaScript's||
operator doesn't work as I wrote at the beginning. It works the following way:Surprised? Actually, it's "compatible" with the traditional
||
operator. It could be written as following function:If you pass a truthy value as
x
, it returnsx
, that is, a truthy value. So if you use it later inif
clause:you get
"Either x or y is truthy."
.If
x
was falsey,eitherXorY
would bey
. In this case you would get the"Either x or y is truthy."
ify
was truthy; otherwise you'd get"Neither x nor y is truthy"
.The actual question
Now, when you know how
||
operator works, you can probably make out by yourself what doesx = x || y
mean. Ifx
is truthy,x
is assigned tox
, so actually nothing happens; otherwisey
is assigned tox
. It is commonly used to define default parameters in functions. However, it is often considered a bad programming practice, because it prevents you from passing a falsey value (which is not necessarilyundefined
ornull
) as a parameter. Consider following example:It looks valid at the first sight. However, what would happen if you passed
false
asflagA
parameter (since it's boolean, i.e. can betrue
orfalse
)? It would becometrue
. In this example, there is no way to setflagA
tofalse
.It would be a better idea to explicitly check whether
flagA
isundefined
, like that:Though it's longer, it always works and it's easier to understand.
You can also use the ES6 syntax for default function parameters, but note that it doesn't work in older browsers (like IE). If you want to support these browsers, you should transpile your code with Babel.
See also Logical Operators on MDN.
Whilst Cletus' answer is correct, I feel more detail should be added in regards to "evaluates to false" in JavaScript.
Is not just checking if title/msg has been provided, but also if either of them are falsy. i.e. one of the following:
So in the line
If title is truthy (i.e., not falsy, so title = "titleMessage" etc.) then the Boolean OR (||) operator has found one 'true' value, which means it evaluates to true, so it short-circuits and returns the true value (title).
If title is falsy (i.e. one of the list above), then the Boolean OR (||) operator has found a 'false' value, and now needs to evaluate the other part of the operator, 'Error', which evaluates to true, and is hence returned.
It would also seem (after some quick firebug console experimentation) if both sides of the operator evaluate to false, it returns the second 'falsy' operator.
i.e.
returns undefined, this is probably to allow you to use the behavior asked about in this question when trying to default title/message to "". i.e. after running
foo would be set to ""
And I have to add one more thing: This bit of shorthand is an abomination. It misuses an accidental interpreter optimization (not bothering with the second operation if the first is truthy) to control an assignment. That use has nothing to do with the purpose of the operator. I do not believe it should ever be used.
I prefer the ternary operator for initialization, eg,
This uses a one-line conditional operation for its correct purpose. It still plays unsightly games with truthiness but, that's Javascript for you.
To add some explanation to all said before me, I should give you some examples to understand logical concepts.
It means if the left side evaluated as a true statement it will be finished and the left side will be returned and assigned to the variable. in other cases the right side will be returned and assigned.
And operator have the opposite structure like below.