Quirky behaviour of "<space>"

I have lately been bugged with an issue of how js consider certain strings being true / false in a boolean context;

let x = Boolean(" ") // Boolean("<space>")
console.log(x) // true

let y = " " == false // "<space>" == false
console.log(y) // true

Why is "<space>" considered true when passed to the Boolean constructor and at the same time considered equivalent to false using the == operator?

Because loose comparison is utterly ridiculous :D
In particular, you're hitting step 10.

If Type(y) is Boolean, return IsLooselyEqual(x, ! ToNumber(y)).

> '-0E+123' == false
> '123E-400' == false

why does this behaviour occur only for "<space>" and not for "%", "_", or any other strings?? why does loose equality treat it as an empty string?

If you follow the algorithm, both sides of <string> == <boolean> get eventually coerced to Number.

  1. If Type(y) is Boolean, return IsLooselyEqual(x, ! ToNumber(y)).
  2. If Type(x) is String and Type(y) is Number, return IsLooselyEqual(! ToNumber(x), y).


"string" == false
// becomes
"string" == Number(false)
// becomes
Number("string") == Number(false)
" " == false
// because
Number(false) === 0
Number(" ") === 0
"%" != false
// because
Number("%") == NaN
NaN !== 0
1 Like

Number(" ") === 0
but how is this coercion done??
Based on unicode code point of <space>??
but that is U+0020.
Null has the corresponding U+0000 code point.
Number(" ") === 0; how is this coercion even reasonable??
I mean if:

Number("<some-glyph>") === NaN
// and <space> should also be
Number("<space>") === NaN
// it's illogical and inconsistent for it to be 0
Number("") === 0
// here it makes some sense for an empty
// string to be coerced to 0

It is not. But that's how it was "standardized".

To me that doesn't make sense, either. There is no number in an empty string, it should've returned NaN.

Missed this question:

No. Number("string") tries to parse it, stripping leading/trailing whitespace. A string of whitespace is treated like an empty string.

1 Like

barbaric logic of standardisation; sad but we can't do much about it😠
Anyway thanks @lightmare for helping me out here!

So to wrap up here's what I understood:

// the normalisation process:

// step.1
" " == false 

// step.2
stripSpaces(" ") == false

// step.3
Number("") == Number(false)

// step.4
0 == 0

// step.5
1 Like