3

Imagine this simple scenario. I have variable that can be plain JS object with one property, ID, that is a number or obj variable can be null. I have simple test() function that checks if the variable is not null and that it must have valid id property.

var obj = { id: 111 };
function test() {
    return (obj && obj.id);
}

I am expecting that this function will always return boolean but in fact it returns undefined if the obj is undefined or value of obj.id if object exists like in case above. Why this function return 111 instead of true.

I am going to rip off hair of my head ... Please illuminate my mind :)

Tjodalv
  • 340
  • 3
  • 15

2 Answers2

4

It's a common misconception. In JS (unlike in e.g. PHP) an expression like x && y does this:

  1. execute the expression x
  2. if the expression x returned true, then execute the expression y as well and return it (y). Otherwise return x (which would be falsy in this case e.g. 0, '', false, null, undefined).

In other words it works more like a ternary expression x ? y : z.

If you want a boolean, then use !!(x && y).

Nurbol Alpysbayev
  • 19,522
  • 3
  • 54
  • 89
  • Good explanation, but what is `z` in the ternary expression? – Yeldar Kurmangaliyev Dec 03 '18 at 16:12
  • @YeldarKurmangaliyev Seriously? ) I've added the ternary expression as an example to demonstrate that binary expression `x && y` is a conditional logical expression just like a ternary expression. `z` is an alternative case of ternary logical expression. – Nurbol Alpysbayev Dec 03 '18 at 16:18
  • 1
    I think @YeldarKurmangaliyev was asking a simple (and good) question. Perhaps a more apt example would be `x ? y : x`, as the `&&` operator will return `x` if it is falsy. – Tyler Roper Dec 03 '18 at 16:19
  • @TylerRoper you're correct, but I am not wrong :) – Nurbol Alpysbayev Dec 03 '18 at 16:20
  • @NurbolAlpysbayev I think your answer was a good explanation, as does Yeldar. Your *"Seriously?"* made it seem like you were averse to what I thought was simply a good discussion question, so I clarified a bit. – Tyler Roper Dec 03 '18 at 16:22
  • 1
    @TylerRoper The "Seriously" was just my reaction after I saw his rating and impressive JS experience. He is also is the first person whom I saw here from my country BTW – Nurbol Alpysbayev Dec 03 '18 at 16:25
  • 1
    @NurbolAlpysbayev Understood :) Simply a hiccup in communication! – Tyler Roper Dec 03 '18 at 16:29
0

When obj is defined, why does if (obj && obj.id) return 111?

The logical AND (&&) operator returns expr1 if it can be converted to false; otherwise, returns expr2.

MDN: Logical Operators - Description (slightly paraphrased)

expr1 (obj) cannot be converted to false, therefore it returns expr2 (111).


Why does it not return true?

Logical operators are typically used with Boolean (logical) values. When they are, they return a Boolean value. However, the && and || actually return the value of one of the specified operands, so if these operators are used with non-Boolean values, they may return a non-Boolean value.

MDN: Logical Operators

Because you are using the logical operator with non-Boolean values, the result will be non-Boolean as well.

Community
  • 1
  • 1
Tyler Roper
  • 21,445
  • 6
  • 33
  • 56