42

I thought I knew about the quirks with == and all the strange type casts in JavaScript, but today I stumbled upon one thing that doesn't make any sense to me:

'\t' == false
// => true

Why is that?

Apparently, '\t' is not a falsy value, and if combined with || it works as excpected:

'\t' || 42
// => '\t'

On the other hand, a toString is also not called on false, see:

'\t' == 'false'
// => false

This led me to thinking that the tab maybe gets converted to a boolean, but:

Boolean('\t') == false
// => false

So, the question is: Why is that?

Golo Roden
  • 140,679
  • 96
  • 298
  • 425
  • 2
    1. Javascript is weird with true and false 2. mainly because a tab is a whitespace and in terms of use cases you usually dont condider an empty string as a word with value imagine having an input mask then you can check wether it has values by doing `if(inputstirng){...}` – jonathan Heindl Aug 06 '19 at 09:08
  • `'\n' == false` true as well – GrafiCode Aug 06 '19 at 09:08
  • "\t" is an "emtpy" string – Estradiaz Aug 06 '19 at 09:09
  • 4
    @jonathanHeindl minor nitpick : Javascript is weird. Not just for booleans. – Eric Duminil Aug 06 '19 at 09:55
  • 3
    They should add `'\t'` to https://eqeq.js.org/ (What's your score there? ;-) ) – Marco13 Aug 06 '19 at 11:25
  • Closely related: [How does Type Coercion in Javascript in the case of object to boolean?](https://stackoverflow.com/q/11264974/1048572). Also [here](https://stackoverflow.com/q/664886/1048572) or [there](https://stackoverflow.com/q/23693089/1048572) – Bergi Aug 06 '19 at 20:20

1 Answers1

42

See Abstract Equality Comparison::

The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

So, in your situation, x is a string, and y is a boolean. The first condition that is fulfilled here is:

  1. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

Turning the check into

'\t' == 0

Which then fulfills:

  1. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.

And ToNumber('\t') === 0:

console.log(Number('\t'));

Turning the check into

0 == 0

which is the same as

0 === 0

or true.

Note that while a string composed of all whitespace is == false, calling Boolean on such a string will return true, because the string has a non-zero length:

console.log(
  Boolean(' '),
  Boolean('\t')
);

Of course, it would be best to always avoid == - use === instead, and you won't have to worry about these silly coercion rules.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320