Why does Javascript’s OR return a value other than true/false?

I saw this construction in order to get the browser viewport width:

function () { return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; }

I understand the browser quirks involved. What I don’t understand is why || returns the value. So I tried this alert(undefined || 0 || 3); and sure enough, it alerts 3. I find this bizarre, because I expect true or false. Could anyone explain what’s going on?

The JavaScript operator || is defined to return the left value if it evaluates to a truthy value, otherwise the right value instead of returning true itself. That’s just how it’s defined in the spec.

I know it can be annoying at times, you might accidentally end up holding a reference to something you don’t want to hold on to, but it also allows for the handy trick your example has. Everything has its pros and cons.

Take a look at the ECMAScript standards section 11.11 Binary Logical Operators

The production LogicalORExpression :
LogicalORExpression ||
LogicalANDExpression is evaluated as

1.Evaluate LogicalORExpression.

2.Call GetValue(Result(1)).

3.Call ToBoolean(Result(2)).

4.If Result(3) is true, return Result(2).

5.Evaluate LogicalANDExpression.

6.Call GetValue(Result(5)).

7.Return Result(6).

So it evaluates the boolean conversion of each operand, but returns the actual value of the operand.

If you want to know how Javascript converts values to a boolean, see section 9.2 ToBoolean

Don’t think of it as “or”. It’s more like a flow-control device within an expression. The value of a || expression is the value of the first subexpression that’s “truthy”. Thus, the evaluation of the series of subexpressions stops at some point, as if

 expr1 || expr2 || expr3


 (function() {
   var rv = expr1;
   if (rv) return rv;
   rv = expr2;
   if (rv) return rv;
   return expr3;

It’s just the way it is by design. ||, like && is a short-circuit operator, the expressions are evaluated in order, they stop after an expression meets the criteria and yield the result of the expression. The same is true of &&:

var  myObj  = { "Test": { "Foo":"Bar" } };
var  myObj2 = { "Foo": "Bar" };

alert(myObj.Test && myObj.Test.Foo); // will alert "Bar";
alert(myObj2.Test && myObj2.Test.Foo); // will alert undefined;

Some values, such as zero, "" or undefined, are treated as false. Anything else is true, so the || operator just returns the first non-zero (ie true) value in the pair that it’s given. This is useful for tricks like the code above, but I’m guessing it wasn’t added to the language just to let you skip the odd if statement.

I suspect it may have originated as a performance tweak, since the higher-level languages (such as BASIC … yes, maybe an odd definition of higher-level) used fixed constants for true and false — often 0 and -1, or 0 and 1.

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Similar Posts