Number.isNaN('asd') === false in Node.js! What gives? - javascript

Try it: In Node.js, or Firefox, open a REPL, and type:
Number.isNaN('asdf');
How can this not be NaN? What is NaN if not this?

You have a misconception here. The fact that NaN means Not a Number does not mean that anything that is not a number is a NaN.
NaN is a special value on floating point arithmethic that represents an undefined result of an operation. For example, 0 / 0 generally yields NaN as a result.
More information here and here.

There is no notion of Number.isNaN() in the language specification. The only specified function is the global isNaN (15.1.2.4), which will correctly return true on anything that isn't a number or cannot get correctly transformed into a number.
Number.isNaN (which returns true on NaN) is probably an implementation detail part of the next standard draft (see remyabel' answer) which could be used internally by isNaN.

Just a note, it seems that Number.IsNaN has limited support.
This output:
console.log(Number.isNaN("blabla"));
Gives false, and false !== NaN:
console.log(false !== NaN)
console.log(false !== Number.NaN);
Here's a reference:
When the Number.isNaN is called with one argument number, the
following steps are taken:
If Type(number) is not Number, return false.
If number is NaN, return true.
Otherwise, return false.
This function differs from the global isNaN function (18.2.3) is that
it does not convert its argument to a Number before determining
whether it is NaN.
I am l33t for I have 1337 reputation.

Try this:
function checkNaN(value)
{
return value !== value;
}
It works because (I believe) NaN is the only thing in JS that does not strictly equal itself.

This is part of the EcmaScript 6 Standard.
Number.isNaN returns whether a value is NaN without coercing the parameter.
Number.isNaN("xmfds"); // false
Number.isNaN("ose"); // false
isNaN returns whether the value is NaN after coercing the parameter to Number type.
isNaN("ose") -> isNaN( Number("ose") ) -> isNaN(NaN); // true

Related

What is wrong in this code, why does it print only the first code block [duplicate]

What are the values in JavaScript that are 'falsey', meaning that they evaluate as false in expressions like if(value), value ? and !value?
There are some discussions of the purpose of falsey values on Stack Overflow already, but no exhaustive complete answer listing what all the falsey values are.
I couldn't find any complete list on MDN JavaScript Reference, and I was surprised to find that the top results when looking for a complete, authoritative list of falsey values in JavaScript were blog articles, some of which had obvious omissions (for example, NaN), and none of which had a format like Stack Overflow's where comments or alternative answers could be added to point out quirks, surprises, omissions, mistakes or caveats. So, it seemed to make sense to make one.
Falsey values in JavaScript
false
Zero of Number type: 0 and also -0, 0.0, and hex form 0x0 (thanks RBT)
Zero of BigInt type: 0n and 0x0n (new in 2020, thanks GetMeARemoteJob)
"", '' and `` - strings of length 0
null
undefined
NaN
document.all (in HTML browsers only)
This is a weird one. document.all is a falsey object, with typeof as undefined. It was a Microsoft-proprietory function in IE before IE11, and was added to the HTML spec as a "willful violation of the JavaScript specification" so that sites written for IE wouldn't break on trying to access, for example, document.all.something; it's falsy because if (document.all) used to be a popular way to detect IE, before conditional comments. See Why is document.all falsy? for details
"Falsey" simply means that JavaScript's internal ToBoolean function returns false. ToBoolean underlies !value, value ? ... : ...; and if (value). Here's its official specification (2020 working draft) (the only changes since the very first ECMAscript specification in 1997 are the addition of ES6's Symbols, which are always truthy, and BigInt, mentioned above:
Argument type
Result
Undefined
Return false.
Null
Return false.
Boolean
Return argument.
Number
If argument is +0, -0, or NaN, return false; otherwise return true.
String
If argument is the empty String (its length is zero), return false; otherwise return true.
BigInt
If argument is 0n, return false; otherwise return true.
Symbol
Return true.
Object
Return true.
Comparisons with == (loose equality)
It's worth talking about falsy values' loose comparisons with ==, which uses ToNumber() and can cause some confusion due to the underlying differences. They effectively form three groups:
false, 0, -0, "", '' all match each other with ==
e.g. false == "", '' == 0 and therefore 4/2 - 2 == 'some string'.slice(11);
null, undefined match with ==
e.g. null == undefined but undefined != false
It's also worth mentioning that while typeof null returns 'object', null is not an object, this is a longstanding bug/quirk that was not fixed in order to maintain compatibility. It's not a true object, and objects are truthy (except for that "wilful violation" document.all when Javascript is implemented in HTML)
NaN doesn't match anything, with == or ===, not even itself
e.g. NaN != NaN, NaN !== NaN, NaN != false, NaN != null
With "strict equality" (===), there are no such groupings. Only false === false.
This is one of the reasons why many developers and many style guides (e.g. standardjs) prefer === and almost never use ==.
Truthy values that actually == false
"Truthy" simply means that JavaScript's internal ToBoolean function returns true. A quirk of Javascript to be aware of (and another good reason to prefer === over ==): it is possible for a value to be truthy (ToBoolean returns true), but also == false.
You might think if (value && value == false) alert('Huh?') is a logical impossibility that couldn't happen, but it will, for:
"0" and '0' - they're non-empty strings, which are truthy, but Javascript's == matches numbers with equivalent strings (e.g. 42 == "42"). Since 0 == false, if "0" == 0, "0" == false.
new Number(0) and new Boolean(false) - they're objects, which are truthy, but == sees their values, which == false.
0 .toExponential(); - an object with a numerical value equivalent to 0
Any similar constructions that give you a false-equaling value wrapped in a type that is truthy
[], [[]] and [0] (thanks cloudfeet for the JavaScript Equality Table link)
Some more truthy values
These are just a few values that some people might expect to be falsey, but are actually truthy.
-1 and all non-zero negative numbers
' ', " ", "false", 'null'... all non-empty strings, including strings that are just whitespace
Anything from typeof, which always returns a non-empty string, for example:
typeof null (returns a string 'object' due to a longstanding bug/quirk)
typeof undefined (returns a string 'undefined')
Any object (except that "wilful violation" document.all in browsers). Remember that null isn't really an object, despite typeof suggesting otherwise. Examples:
{}
[]
function(){} or () => {} (any function, including empty functions)
Error and any instance of Error
Any regular expression
Anything created with new (including new Number(0) and new Boolean(false))
Any Symbol
true, 1, "1" and [1] return true when compared to each other with ==.
Don't forget about the non-empty string "false" which evaluates to true
Just to add to #user568458's list of falsy values:
In addition to integer number 0, the decimal number 0.0, 0.00 or any such zeroish number is also a falsy value.
var myNum = 0.0;
if(myNum){
console.log('I am a truthy value');
}
else {
console.log('I am a falsy value');
}
Above code snippet prints I am a falsy value
Similarly hex representation of the number 0 is also a falsy value as shown in below code snippet:
var myNum = 0x0; //hex representation of 0
if(myNum){
console.log('I am a truthy value');
}
else {
console.log('I am a falsy value');
}
Above code snippet again prints I am a falsy value.
Addition to the topic, as of ES2020 we have a new value which is falsy, it's BigInt zero (0n):
0n == false // true
-0n == false // true
0n === false // false
-0n === false // false
So with this, we now have 7 "falsy" values in total (not including document.all as mentioned by user above since it's part of DOM and not JS).

Javascript "implicit" condition in IF statements [duplicate]

What are the values in JavaScript that are 'falsey', meaning that they evaluate as false in expressions like if(value), value ? and !value?
There are some discussions of the purpose of falsey values on Stack Overflow already, but no exhaustive complete answer listing what all the falsey values are.
I couldn't find any complete list on MDN JavaScript Reference, and I was surprised to find that the top results when looking for a complete, authoritative list of falsey values in JavaScript were blog articles, some of which had obvious omissions (for example, NaN), and none of which had a format like Stack Overflow's where comments or alternative answers could be added to point out quirks, surprises, omissions, mistakes or caveats. So, it seemed to make sense to make one.
Falsey values in JavaScript
false
Zero of Number type: 0 and also -0, 0.0, and hex form 0x0 (thanks RBT)
Zero of BigInt type: 0n and 0x0n (new in 2020, thanks GetMeARemoteJob)
"", '' and `` - strings of length 0
null
undefined
NaN
document.all (in HTML browsers only)
This is a weird one. document.all is a falsey object, with typeof as undefined. It was a Microsoft-proprietory function in IE before IE11, and was added to the HTML spec as a "willful violation of the JavaScript specification" so that sites written for IE wouldn't break on trying to access, for example, document.all.something; it's falsy because if (document.all) used to be a popular way to detect IE, before conditional comments. See Why is document.all falsy? for details
"Falsey" simply means that JavaScript's internal ToBoolean function returns false. ToBoolean underlies !value, value ? ... : ...; and if (value). Here's its official specification (2020 working draft) (the only changes since the very first ECMAscript specification in 1997 are the addition of ES6's Symbols, which are always truthy, and BigInt, mentioned above:
Argument type
Result
Undefined
Return false.
Null
Return false.
Boolean
Return argument.
Number
If argument is +0, -0, or NaN, return false; otherwise return true.
String
If argument is the empty String (its length is zero), return false; otherwise return true.
BigInt
If argument is 0n, return false; otherwise return true.
Symbol
Return true.
Object
Return true.
Comparisons with == (loose equality)
It's worth talking about falsy values' loose comparisons with ==, which uses ToNumber() and can cause some confusion due to the underlying differences. They effectively form three groups:
false, 0, -0, "", '' all match each other with ==
e.g. false == "", '' == 0 and therefore 4/2 - 2 == 'some string'.slice(11);
null, undefined match with ==
e.g. null == undefined but undefined != false
It's also worth mentioning that while typeof null returns 'object', null is not an object, this is a longstanding bug/quirk that was not fixed in order to maintain compatibility. It's not a true object, and objects are truthy (except for that "wilful violation" document.all when Javascript is implemented in HTML)
NaN doesn't match anything, with == or ===, not even itself
e.g. NaN != NaN, NaN !== NaN, NaN != false, NaN != null
With "strict equality" (===), there are no such groupings. Only false === false.
This is one of the reasons why many developers and many style guides (e.g. standardjs) prefer === and almost never use ==.
Truthy values that actually == false
"Truthy" simply means that JavaScript's internal ToBoolean function returns true. A quirk of Javascript to be aware of (and another good reason to prefer === over ==): it is possible for a value to be truthy (ToBoolean returns true), but also == false.
You might think if (value && value == false) alert('Huh?') is a logical impossibility that couldn't happen, but it will, for:
"0" and '0' - they're non-empty strings, which are truthy, but Javascript's == matches numbers with equivalent strings (e.g. 42 == "42"). Since 0 == false, if "0" == 0, "0" == false.
new Number(0) and new Boolean(false) - they're objects, which are truthy, but == sees their values, which == false.
0 .toExponential(); - an object with a numerical value equivalent to 0
Any similar constructions that give you a false-equaling value wrapped in a type that is truthy
[], [[]] and [0] (thanks cloudfeet for the JavaScript Equality Table link)
Some more truthy values
These are just a few values that some people might expect to be falsey, but are actually truthy.
-1 and all non-zero negative numbers
' ', " ", "false", 'null'... all non-empty strings, including strings that are just whitespace
Anything from typeof, which always returns a non-empty string, for example:
typeof null (returns a string 'object' due to a longstanding bug/quirk)
typeof undefined (returns a string 'undefined')
Any object (except that "wilful violation" document.all in browsers). Remember that null isn't really an object, despite typeof suggesting otherwise. Examples:
{}
[]
function(){} or () => {} (any function, including empty functions)
Error and any instance of Error
Any regular expression
Anything created with new (including new Number(0) and new Boolean(false))
Any Symbol
true, 1, "1" and [1] return true when compared to each other with ==.
Don't forget about the non-empty string "false" which evaluates to true
Just to add to #user568458's list of falsy values:
In addition to integer number 0, the decimal number 0.0, 0.00 or any such zeroish number is also a falsy value.
var myNum = 0.0;
if(myNum){
console.log('I am a truthy value');
}
else {
console.log('I am a falsy value');
}
Above code snippet prints I am a falsy value
Similarly hex representation of the number 0 is also a falsy value as shown in below code snippet:
var myNum = 0x0; //hex representation of 0
if(myNum){
console.log('I am a truthy value');
}
else {
console.log('I am a falsy value');
}
Above code snippet again prints I am a falsy value.
Addition to the topic, as of ES2020 we have a new value which is falsy, it's BigInt zero (0n):
0n == false // true
-0n == false // true
0n === false // false
-0n === false // false
So with this, we now have 7 "falsy" values in total (not including document.all as mentioned by user above since it's part of DOM and not JS).

Why is there an isNaN() function in JavaScript but no isUndefined()?

Why is there an isNaN() function in JavaScript whilst isUndefined() must be written as:
typeof(...) != "undefined"
Is there a point I don't see?
In my opinion its really ugly to write this instead of just isUndefined(testValue).
There is simply no need for an isUndefined() function. The reason behind this is explained in the ECMAScript specification:
(Note that the NaN value is produced by the program expression NaN.) In some implementations, external code might be able to detect a difference between various Not-a-Number values, but such behaviour is implementation-dependent; to ECMAScript code, all NaN values are indistinguishable from each other.
The isNaN() function acts as a way to detect whether something is NaN because equality operators do not work (as you'd expect, see below) on it. One NaN value is not equal to another NaN value:
NaN === NaN; // false
undefined on the other hand is different, and undefined values are distinguishable:
undefined === undefined; // true
If you're curious as to how the isNaN() function works, the ECMAScript specification also explains this for us too:
Let num be ToNumber(number).
ReturnIfAbrupt(num).
If num is NaN, return true.
Otherwise, return false.
A reliable way for ECMAScript code to test if a value X is a NaN is an expression of the form X !== X. The result will be true if and only if X is a NaN.
NaN !== NaN; // true
100 !== 100; // false
var foo = NaN;
foo !== foo; // true
The use case var === undefined works almost everywhere, except for the cases covered by this answer, where either undefined is assigned a value, or var is undefined.
The reason such a function cannot exist, is clear from the latter case. If var is undefined, then calling the supposed function isUndefined(var) will result in a ReferenceError. However introducting a new keyword, e.g. isundefined var could address this issue.
But despite being valid, both of the above cases are poor uses of javascript. This is the reason I believe such a keyword does not exist.
isUndefined could be written as
testValue === undefined
like for every other value.
This does not work with NaN however, as NaN !== NaN. Without the ability to use a comparison, there was need for an isNaN function to detect NaN values.
This isn't a direct answer to the question as others have already answered, it's more to highlight libraries that contain an isUndefined() function for anybody looking for quick solution and they're in a position to use them.
Underscore and Lo-dash both contain an isUndefined() function, the latter, because it's built upon Underscore.
http://underscorejs.org/#isUndefined
https://lodash.com/docs#isUndefined

Why does `isFinite(null) === true`?

The following are examples that make sense to me.
isFinite(5) // true - makes sense to me, it is a number and it is finite
typeof 5 // "number"
isFinite(Infinity) // false - makes sense for logical reasons
typeof Infinity // "number"
isFinite(document) // false - makes sense as well, it's not even a number
typeof document // "object"
The following is where I get confused.
isFinite(null) // true - Wait what? Other non-number objects returned false. I see no reason?
typeof null // "object"
I just don't see the reasoning behind this.
What I'd like is the most low-level answer possible.
I think null is being converted to 0, why? What other impacts does this have?
The ECMAScript spec (5.1) defines isFinite to act as such:
isFinite (number)
Returns false if the argument coerces to NaN, +∞, or −∞, and otherwise returns true.
If ToNumber(number) is NaN, +∞, or −∞, return false.
Otherwise, return true.
In other words, isFinite is calling ToNumber on whatever's passed in, and then comparing it to either pos/neg infinity or NaN.
In JavaScript (note the use of != instead of the more common !==, causing the type cast):
function isFinite(someInput) {
return !isNaN(someInput) &&
someInput != Number.POSITIVE_INFINITY &&
someInput != Number.NEGATIVE_INFINITY;
}
(As noted in the comments below, someInput != NaN is not needed, as NaN is defined to not be equivalent to everything, including itself.)
Now, why is null converted to zero (as opposed to undefined)? As TylerH says in the comments, null means that a value exists, but is empty. The mathematical representation of this is 0. undefined means that there isn't a value there, so we get NaN when trying to call ToNumber on it.
http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.2.5
However, ECMAScript 6 is bringing along a non-converting isFinite as a property of Number. Douglas Crockford suggested it here: http://wiki.ecmascript.org/doku.php?id=harmony:number.isfinite
From MDN:
The global isFinite() function determines whether the passed value is
a finite number. If needed, the parameter is first converted to a
number.
So, it's converted to a number...
isFinite(null)
isFinite(+null) //convert to a number
isFinite(0) // true because +null or Number(null) = 0
The spec says that the global isFinite() method will forcibly convert the parameter to a number.
You could, however, use (at your own risk) the EcmaScript 6 spec's Number.isFinite() which doesn't perform this conversion.
Number.isFinite(null) // false
Or, like lodash and underscore do it...
var _.isFinite = function(obj) {
return isFinite(obj) && !isNaN(parseFloat(obj));
};
isFinite calls ToNumber on its argument. So
> Number(null)
0
> Number(document)
NaN
> isFinite(0)
true
> isFinite(NaN)
false
> isFinite(null)
true
> isFinite(document)
false
Because, if you say
Number(null) === 0 which is finite
See To Number Conversions
Which says that, for argument type null result is +0
isFinite typecasts it's argument to a number, if it's not already a number. Essentially you have isFinite(Number(null)) and Number(null) === 0. Which is finite.
Beside null, you find these examples interesting too:
alert(isFinite(' ')); //true
alert(isFinite('')); //true
alert(isFinite(null)); //true
alert(isFinite(!undefined)); //true
In JavaScript implicit conversion take place, This conversion try to convert bool to integer when comparing numbers with boolean, or number to string when comparing string with numbers. If you treat any data-type as number it implicitly converted to number so all above cases return zero which is finite. See Here
If you try Number(undefined) it give you a NaN on negate this would produce a 1 which is finite.

Is it possible to detect NaN without using isNaN?

Can I write a isNan() function with JavaScript? Can JavaScript check for sure that a variable is NaN without native isNaN function?
This is a interview question.
If it is a number, and is not equal to itself, it is NaN.
Note: As #pst has pointed out, the number constraint is unnecessary. NaN appears to be the only value in JS != itself.
Complete solution for this question:
var is_NaN = function(n) {
return (n !== n);
}
is_NaN(1/'a'); // true
isNaN(1/'a'); // true
Because in JavaScript NaN isn't equal to itself. An expression NaN === NaN always returns false
The second solution:
You can use built-in isFinite function. isFinite checks whether the input is a number that is neither Infinity nor NaN.
isFinite(NaN) // false
isFinite(Infinity) // false
isFinite(1) // true
isFinite(true) // true, because argument true is equal to 1
isFinite('a') // false
isFinite(1/'a') // false
ECMA 6
Number.isNaN(42) === false
Number.isNaN(NaN) === true
http://es6-features.org/#NumberTypeChecking

Categories