20

I was playing around with JSconsole and found something strange. The value of "0" is false

"0" == false
=> true

The value of false when used in ternary returns the second value

false ? 71 : 16
=> 16

However the value "0" which equals false when used in ternary returns the first value.

"0" ? 8 : 10
=> 8

However, if you use 0 as the value, it returns the second value

0 ? 4 : 5
=> 5

0 == "0"
=> true

I'm afraid this doesn't make sense to me.

Octavia Togami
  • 4,186
  • 4
  • 31
  • 49
Richard Hamilton
  • 25,478
  • 10
  • 60
  • 87
  • 4
    `"0"` is a string that's not empty, i.e. not a falsy value – rev Jun 05 '15 at 16:04
  • 1
    Then why does "0" equal false when using comparison `==` – Richard Hamilton Jun 05 '15 at 16:05
  • 1
    `==` in Javascript doesn't make sense. `'' == 0`, `0 == '0'`, but `'' != '0'`. Don't assume that because `x == y`, `x` and `y` will behave remotely the same. – user2357112 Jun 05 '15 at 22:23
  • 2
    This is one of the more confusing features of Javascript. There are at least four (!) scenarios where a value can `== false` yet not be "falsey". I've been putting together a reference guide under the question [All falsey values in JavaScript](http://stackoverflow.com/questions/19839952/all-falsey-values-in-javascript-values-where-value-is-true). I think I've got all of the falsey-related quirks and gotchas documented there... if I've missed any, please comment! – user56reinstatemonica8 Jun 05 '15 at 23:30
  • @CodesInChaos, you are mistaken: `!!"0"` evaluates to `true`. Agreed about `==`, though. – Andreas Rossberg Jun 06 '15 at 11:43

4 Answers4

21

Non-empty string is considered as truth value in conditional statements, conditional expressions and conditional constructs.

But when you compare a string with a number with ==, some conversion will take place.

When comparing a number and a string, the string is converted to a number value. JavaScript attempts to convert the string numeric literal to a Number type value. First, a mathematical value is derived from the string numeric literal. Next, this value is rounded to nearest Number type value.

And == don't have the Transitive Property of Equality:

you can't say if a == b, b == c, then a == c.

An example will be:

"0" == false // true
false == "\n" //true

and guess the result of "0" == "\n"? Yes, the result is false.

xdazz
  • 158,678
  • 38
  • 247
  • 274
17

"0" is a string of length>0 which is true. Try

0 ? 8 : 10

and see. It will return 10.

== does type conversion and hence when you do

"0" == false

it returns true. When you do

0 == "0" //true

It also returns true as again type conversion is taking place. Even though one is a number and the other one is a string it returns true. But if you use ===, no type conversion is done and 0 === "0" will return false.

A nice explanation of == & === is given here.

From the docs:

The equality operator(==) converts the operands if they are not of the same type, then applies strict comparison.

The identity operator(===) returns true if the operands are strictly equal with no type conversion.

Community
  • 1
  • 1
Zee
  • 8,420
  • 5
  • 36
  • 58
6

I'm afraid this is an example of why you should use === - plain old == performs type conversion. Try

"0"===false
Evan Knowles
  • 7,426
  • 2
  • 37
  • 71
  • 2
    But wait, `"0"===true` yields false either. This may not answer the question straightaway, I guess. – TaoPR Jun 05 '15 at 17:34
  • 3
    @TaoP.R. If you want to convert a value to a boolean in a way that respects how it acts in a ternary operator, use `!!value`. As in `!!"0" === true`. – Random832 Jun 05 '15 at 21:27
  • @Random832 Would `Boolean()` be completely equivalent? (i.e. `Boolean(x) === !!x` for all values of `x`) - that's probably the more explicit/readable/obvious way. – Bob Jun 06 '15 at 07:37
1

JavaScript leads to tons of WTFs.

Check out "Javascript WTF" on YouTube...

Essentially, you are requesting a conversion from string to boolean.

This is defined as "string is not empty".

Whereas you assumed that javascript does string -> int -> boolean if the string happens to contain a number.

It's sensible. But these automatic conversions lead to programming errors, which is why I prefer typesafe languages (with compile time type checking) for larger projects.

For fun, try these:

("0" * 1) ? 71 : 16
("0" + false) ? 71 : 16
Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194