Binary logical operators like && (and) and || (or) are another area where things get a bit strange in JavaScript.

In other languages we are used to expressions of || and && to evaluate to boolean values. Here is an entirely made up example in C#, which would look very similar in Java:

bool result = hasTimedOut || (hasReceived && initialValueSet);
// result will always be true or false

In JavaScript, however, it is not the case that || and && return a boolean value. Instead these operators evaluate each of their operands, then return the value of the chosen operand according to the rules of the operation.

Now, if the value of all the operands are Boolean then no problem. However, if the operands are something else, like Number, String or Object, then you might get one of those as the result of the expression.

"this" || "that"
>>> "this"

0 || "1"
>>> "1"

The operands are of course converted to true or false using JavaScript’s conversion rules when evaluating the statements, but the returned result is the value of the operand and not it’s truthy or falsy value.

This property of || is used a lot for supplying default values when you are unsure if a value is undefined or null:

var myObj = myObj || {};

However, it can be very dangerous to depend on this mechanism without considering that some values may be zero, an empty string or similar for a good reason (all of which would evaluate to falsy). In these cases you might get the default value more often than you intended:

// myParameter will become 1 if undefined, null or 0 (zero) is encountered.
var myParameter = myParameter || 1;

var myString = myString || "none";  // will never allow myString === ""

Source: conversation with colleagues and the ECMAScript specification, page 83.

Advertisements