close

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:

  1. They short-circuit evaluations
  2. 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.

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 Foxbrush 的頭像
    Foxbrush

    Foxbrush

    Foxbrush 發表在 痞客邦 留言(0) 人氣()