4

Why does the following code produce a == 3?

var x = "abc";
var y = 3;
var z = "xyz";
var a = x && y || z;

http://jsfiddle.net/thinkingmedia/qBZAL/

I would have expected this to result in a == true.

Why is the logical operator evaluating "abc" as true but doesn't evaluate 3 as true. Instead it produces 3 as the result.

Furthermore, if you change y = 0 then a == "xyz" which means that && treated 0 as false. What happen to treating a number as a number?

What's going on here with the logical operators?

4
  • anyone have a better title for this question? Commented Apr 24, 2014 at 12:40
  • 3
    why didn't you ask at Stack Overflow? meta.stackexchange.com/a/129632/165773 Commented Apr 24, 2014 at 12:57
  • @gnat seemed like a general programming question. Commented Apr 24, 2014 at 13:41
  • 3
    "Why" questions are difficult to answer. Why does the code produce that result? Because that is what the ECMAScript specification states it should return, and the implementation is a correct implementation of the specification. Is that answer satisfying or unsatisfying? Commented Apr 24, 2014 at 18:37

3 Answers 3

15

This is to be expected.

In JavaScript (and many other languages), not only Booleans themselves are true or false, but other objects can be truthy or falsey as well (See the docs on mdn):

The value […] is converted to a boolean value, if necessary. If value is […] is 0, -0, null, false, NaN, undefined, or the empty string (""), [it is] false. All other values, including any object or the string "false", create […] true.

The logical operators || and && don't return true or false, rather they return the last argument to influence whether they are truthy or falsey (reference):

  • expr1 && expr2 – Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.
  • expr1 || expr2 – Returns expr1 if it can be converted to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand is true; if both are false, returns false.
Sign up to request clarification or add additional context in comments.

Comments

10
  1. The first step is to evaluate "abc" && 3.

    • false && 3 would return false,
    • true && 3 would return 3.

    "abc" is not false, so JavaScript takes the second part, i.e. 3.

The second step is to evaluate 3 || "xyz". Here, JavaScript takes the first value which is not null, i.e. 3. This is similar to this.firstObject ?? this.defaultValue in C#: the second part is taken only when the first part is null.

1 Comment

Just to add a small bit, the gotcha here is that the logical AND and OR operators do not return a boolean value, they return the value of the last operand that they actually evaluate. false || null will equal null for example.
1

the side effect is that you can do things like this:

x = x || {};

to set a variable to a default if it is not set.

Or

TrackingManager && TrackingManager.track("user was here")

to avoid bulkier if statements.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.