Seeing this question: Is there a (built-in) way in JavaScript to check if a string is a valid number? and this: jsperf, one of the presented approaches is this (mutatis mutandis):
var a = "123" var b = "123b" if ( +a === +a ) // true if ( +b === +b ) // false
How does this logic work internally in JavaScript to make this possible?
My question is not how to check if a string is a valid number – this is already answered here: Validate decimal numbers in JavaScript - IsNumeric(). I want to understand how the statement +a === +a
works.
Variables declared using var are created before any code is executed in a process known as hoisting. Their initial value is undefined . 'use strict'; console. log(x); // undefined (note: not ReferenceError) console.
This means that if a variable is defined in a loop or in an if statement it can be accessed outside the block and accidentally redefined leading to a buggy program. As a general rule, you should avoid using the var keyword.
Instead of relying on convention, the introduction of the const keyword gives us an explicit option for declaring that which does not change. To use the const keyword, simply swap it out with var and now that value cannot be modified.
+
converts the value to a number.
a
gets converted to 123
and 123 === 123
.
b
gets converted to NaN
but NaN !== NaN
(because NaN
is never equal to another NaN
according step 4a of the equality rules).
The +
operator here is known as the Unary Plus.
The unary plus operator precedes its operand and evaluates to its operand but attempts to converts it into a number, if it isn't already.
+"123"
evaulates as 123
.
+a === +a -> +"123" === +"123" -> 123 === 123 -> true
+"123b"
evaluates as NaN
(Not a Number), as the b
character cannot be converted with the Unary Plus as without any prefix (like 0x
for hexadecimal) the Unary Plus will assume the value is decimal (0-9). NaN
is a special case in that it does not compare against anything, including itself:
NaN === NaN -> false NaN !== NaN -> true
Because of this, our +b
test case fails:
+b === +b -> +"123b" === +"123b" -> NaN === NaN -> false
If you want both to evaluate to true we can add an isNaN()
call at the end:
if ( +a === +a || isNaN(+a) ) if ( +b === +b || isNaN(+b) )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With