Grauw’s blog
On && and || in Javascript
For a better understanding of the &&
(‘and’) and ||
(‘or’) operators in Javascript, you need to know about two of their properties:
- They short-circuit evaluations
- They evaluate to their last evaluated operator
Short-circuiting evaluations
Like many other languages Javascript’s &&
and ||
operators short-circuit evaluations, that is, for &&
if the first operand evaluates to false
, the second operand is never evaluated because the result would always be false
. Similarly, for ||
if the result of the first operand is true
, the second operand is never operated.
This means that in the following expression, x
will never be compared to y
.
true || x == y
This short-circuiting is great for performance, as it allows significant bits of calculations to be skipped. In addition to that, it lets you to write e.g. the following in one expression without getting an ‘object has no properties’ error:
oNode && oNode.firstChild
Be mindful though when using &&
with code that has side effects, e.g. say you have two objects with an isValid()
method which returns false
when a validation error occurs and additionally outputs an error message:
x.isValid() && y.isValid()
Here, if x has an error, y will never be evaluated and thus the error message will never be shown.
Evaluation to the last evaluated operator
One detail people often do not realise about the operators &&
and ||
in Javascript, is that they do not return a boolean value (true
or false
), but the value of the last operand they evaluate. So:
false || null
Will return null
, and not false
. Additionally, because of the above mentioned short-circuiting:
null && false
Will return null
as well.
Usually, you don’t even notice this behaviour because the if
statement doesn’t care whether it gets a boolean or not, but occasionally this may lead to unexpected results when you are not aware of this.
Upside of the story is that by using this behaviour and applying these operators more generally, you can make your code shorter by removing duplication, and evaluate to more predictable results. Some examples that show some useful applications of this, along with their equivalent expression using the ternary ?:
operator:
oObject.textValue || '' oObject.textValue ? oObject.textValue : ''
This uses ||
to specify a ‘default value’ in case textValue
is undefined
or null
, and avoids writing oObject.textValue
twice.
Similarly, Internet Explorer does not support the localName
property on XML elements, you have to use baseName instead. Using ||
, it is easy to write:
(oElm.localName || oElm.baseName) == 'data' (oElm.localName ? oElm.localName : oElm.baseName) == 'data'
If you need some property from either of two objects:
(oElm1 || oElm2).firstChild (oElm1 ? oElm1 : oElm2).firstChild
Using &&
is useful if you only need to return some property if the object is not null
:
oNode && oNode.firstChild oNode ? oNode.firstChild : null
This of course only works if the expression before the &&
evaluates to a value that you want to return.
If you combine &&
with ||
, you get a guard-like construct similar to the ternary operator:
oNode && oNode.firstChild || null oNode ? oNode.firstChild ? oNode.firstChild : null : null
Similar, but different in the details, as you can see in the ?:
-equivalent; the &&
||
version will additionally make sure that firstChild
returns null
if either oNode
or oNode.firstChild
do not exist, instead of possibly returning undefined
. Perhaps this is not the best of examples, because in the DOM firstChild
is null
when there is none, but you get the idea.
Fun fact, for a very long time the Python programming language did not have a ternary operator and instead programmers used the Python and
and or
operators.
Just a small evolution of the last example:
oNode && oNode.firstChild || oNode || null oNode ? oNode.firstChild ? oNode.firstChild : oNode : null
By stringing a bunch of these together, you can use it in even crazier ways which can make your code shorter and easier to read if you understand the language construct properly.
Grauw
Comments
by Ceasar at 2012-12-31 00:34
What do you mean:
```
In fact, for a very long time the Python programming language did not have ?: and instead programmers used the Python and and or operators.
```
Python still does not have a ternary operator (it does have `a if b else c` if that’s what you mean).
Re: a if b else c by Grauw at 2012-12-31 12:33
Yes that’s what I mean. Syntax is different but function is the same. Why are you saying that is not the ternary operator? What else would you imagine it to be?
(p.s. I updated that paragraph to say ternary operator instead of ?:
given the syntactic difference, and added a link to van Rossum’s announcement.)
Strong Work, Keep It Up by Bryan O'Doyle at 2013-08-17 21:16
Thanks for the time and effort which went into preparing this thorough treatment of the
subject. Until the proper use of these becomes second nature, I’ll keep a link to your
resource handy!
Nice article by FS at 2013-11-10 18:33
Good article on the && and || operators.
Just wanna discuss one question with you:
In the last small evolution example, it reads,
oNode && oNode.firstChild || oNode || null
oNode ? oNode.firstChild ? oNode.firstChild : oNode : null
Does this section want to express “the result is the same” or “the logic is the same” ?
For example, if we use a more generic form to express that example:
var A = true, B = false, C = undefined, a;
a = A && B || C || null; // In S0, a is null
a = A ? B ? B : C : null; // In S1, a is undefined
a = A ? B ? B : C ? C : null : null; // In S2, a is null
S2 gets the same value as S0 does, but S1 doesn’t since S2 and S0 run the equivalent checking logics.
However if we replace C’s value with A’s value then S0, S1 and S2 would get the same value.
So I am wondering what the last example is expressing ?
Re: Nice article by Grauw at 2014-01-05 17:26
Hi FS,
However if we replace C’s value with A’s value then S0, S1 and S2 would get the same value.
Indeed, in the last example, there is no “C”, just A and B (where A appears twice). I meant to illustrate that the version using && and || is a bit shorter and nicer on the eyes.
However, I think if there was a C, the &&||
-version yields a better result (never undefined). The ?:
-version would have to get even longer to replicate that.
question about x.hasError() && y.hasError() by Serch at 2014-02-06 05:31
Hi!, Thanks for such a handy resource. I’m not sure what you mean when you say:
”x.hasError() && y.hasError()
Here, if x has an error, y will never be evaluated and thus the error message will never be shown.”
What I understand is the following:
var x = { hasError: function(){ console.log(“error on x”); return true;} };
var y = { hasError: function(){ console.log(“error on y”); return true;} };
in this case var test = x.hasEror && y.hasError(); will evaluate both x and y,
output:
error on x
error on y
Could you clarify that point?
Thanks,
Serch
Re: question about x.hasError() && y.hasError() by Grauw at 2014-02-07 19:19
Hey Serch, you’re right, it’s a bad example… I’ve changed it!
Thanks by Luke Gedeon at 2012-06-30 22:32
Great explanation of “and” and “or” in JS. I never really thought about stringing them that way before. You have just increased my code quality significantly.