From: http://www.grauw.nl/blog/entry/510
-------------------------------------------------
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 writingoObject.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 theDOM 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.
留言列表