Default Operator

The boolean operators `&&`

and `||`

also use *truthy* and *falsy* to resolve each of the operands to a boolean value.

From your previous experiences with other programming languages you may be led to believe that the result of a boolean operation is always `true`

and `false`

. This is not the case in JavaScript.

In JavaScript, the result of a boolean operation is the value of the operand that determined the result of the operation. Let's clarify that with an example:

AdvancedTechniques/Demos/default-operator.html

---- C O D E O M I T T E D ---- var a = 0, b = NaN, c = 1, d = "hi"; var result = ( a || b || c || d ); alert("Result: " + result); result = ( d && c && b && a ); alert("Result: " + result); ---- C O D E O M I T T E D ----

The first boolean expression `( a || b || c || d )`

is evaluated from left to right until a conclusion is made. The `||`

is the boolean OR operator, which only needs one of the operands to be `true`

(truthy) for the operation result to be `true`

:

`a`

is 0, which is`falsy`

. The evaluation continues with the remaining operands because`falsy`

doesn't determine anything yet. We need one`truthy`

value for the whole statement to be true.`b`

is`NaN`

, also`falsy`

. We have the same situation and we need to continue evaluating.`c`

is 1,which is`truthy`

. We no longer need to continue evaluating the remaining operands because we already know the expression will result`true`

.

But here's the catch. Instead of resulting strictly `true`

, it will result in the `truthy`

value that ended the evaluation, the value of `c`

in this case. The message displayed will be "Result: 1".

As you might already expect, the `&&`

(boolean AND operator) works in a similar fashion, but with opposite conditions. The AND operator returns the value of the last operand evaluated, which is either the first `falsy`

operand or, in the case that all operands are `truthy`

, the last operand in the expression. If for the expression `( d && c && b && a )`

we follow the same sequence we did for the OR operator we will see that, `d`

and `c`

are both `truthy`

so we need to keep going, then we get to `b`

, which is `falsy`

and causes the evaluation to stop and return `b`

. The message displayed then is "Result: NaN".

You may be reading all this and thinking how can this be of any use. It turns out that this behavior of returning the first conclusive value can be very handy when ensuring that a variable is initialized.

Let's take a look at the function below.

function checkLength(text, min, max){ min = min || 1; max = max || 10000; if (text.length < min || text.length > max) { return false; } return true; }

The first two lines in this function make sure that `min`

and `max`

always have a valid value. This allows the function to be called like `checkValue("abc")`

. In this case the `min`

and `max`

parameters will both start with the `undefined`

value.

When we reach the line `min = min || 1;`

we are simply assigning 1 to `min`

, ensuring it overrides the `undefined`

. Similarly we assign 10000 to `max`

.

If we had passed actual values for these parameters as in `checkLength("abc", 2, 10)`

these values would be kept because they are `truthy`

.

With this usage of the `||`

we are effectively providing default values for these two parameters. That's why this operator, in this context, is also called the *Default Operator*.

The default operator replaces more verbose code like:

if (min === undefined) { min = 1; }

...becomes simply...

min = min || 1;

Here is another example of shortening your code using the default operator:

var contactInfo; if (email) { contactInfo = email; } else if (phone) { contactInfo = phone; } else if (streetAddress) { contactInfo = streetAddress; }

...is greatly shortened to...

var contactInfo = email || phone || streetAddress;

Be careful using the default operator with variables that can accept *falsy* values. The following example illustrates the danger:

AdvancedTechniques/Demos/default-operator-gotcha.html

---- C O D E O M I T T E D ---- function calculatePrice(basePrice, tax) { basePrice = basePrice || 0; tax = tax || .1; //default tax is 10% var price = (basePrice * (1 + tax)).toFixed(2); alert("The price including tax is " + price); } calculatePrice(100, 0); //no tax ---- C O D E O M I T T E D ----

The `calculatePrice()`

function uses the default operator to set a default `tax`

of `.1`

. The problem comes when we pass `0`

as the value for `tax`

. Our intent is to indicate that there is no tax; however, because `0`

is falsy, `tax = tax || .1`

evaluates to `.1`

.

We can fix this by changing `tax = tax || .1`

to `tax = (tax === 0) ? 0 : tax || .1;`

.