javascript why isNaN(new Date()) is false - javascript

Hi I'm looking for a good explanation for this simple code
why isNaN(new Date(some date)) gives false? (typeof return object)
This is an object and as far as i know isNaN function explicitly converts to a number, so if I pass different object to isNaN it returns true.

The first thing that isNaN() does is convert its parameter to a number (as you yourself wrote). If the parameter is an object, that's done by calling the .valueOf() method of the object. In the case of Date instances that returns the timestamp, and it won't be NaN for any valid Date.
Try this:
alert(isNaN({ valueOf: function() { return 12; } }));
And for an invalid date:
alert(isNaN(new Date("potatoes")));
That'll be true. If you want a stricter isNaN you can use Number.isNaN:
alert(Number.isNaN(NaN)); // true
The version of isNaN on the Number constructor won't coerce its argument to a number; it's job is to say whether the thing you pass in is the NaN value, without any type casting. So by that function, there's one and only one NaN.

Checking with isNaN tries to convert its parameter to number and if this is not a number then only it gives you the result true. But if the date passed as the parameter it shows you the false as it is converted to number.
Whatever you pass in the parameter if that returns number successfully then it give you the result to be false else it gives you the true.

Related

Why isNaN([3]) is false in JavaScript?

I use Chrome browser 60.x, and test the code isNaN([3]).
The result is false, but I cannot understand it.
[3] is an Array, and it is not empty.
I think [3] is array object, and it is not an number.
Otherwise the result of isNaN(["ABC"]) is true.
And another result of isNaN([1,2,3]) is true.
So I guess javascript engine is force changing array to number which the array has a single element.
Please let me know what is happened isNaN function for array parameter.
ref1: Why is isNaN(null) == false in JS?
ref2: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN
[EDIT] Thank you everyone for answering.
I understand javascript parsed the value implicitly before comparison.
And I found a useful link while reading Nina Scholz's answer.
The comparison table : http://dorey.github.io/JavaScript-Equality-Table/
When you use isNaN it tries to parse your input value into the number and then checks if it is NaN or not.
See some examples.
For an array with one item, the Number() function returns an object, which actually hold the first item as a value (see console.log). For many items it returns NaN, so you get isNaN's result -> true.
const a = new Number([3]);
console.log(`a is ${a}`);
console.log(`isNaN(a) - ${isNaN(a)}`);
const b = new Number([3,4,5]);
console.log(`b is ${b}`);
console.log(`isNaN(b) - ${isNaN(b)}`);
According to the rules for equality comparisons and sameness, the array is converted, first with toString and then to a number for checking.
console.log(isNaN([3]));
console.log(isNaN('3')); // convert with toString to a primitive
console.log(isNaN(3)); // convert to number
Javascript works in the following way: It tries to convert the object to integer if the argument of the function is expected to be an integer. For example running
x = increment([3])
will result in x = 4. Therefore running
isNan([3])
will result in false, since [3] gets converted to 3 and 3 is a number. Similarly, ["ABC"] cannot get converted to integer, therefore isNaN(["ABC"]) = true. Also, javascript fails to convert [1,2,3] to a number, since there are three numbers in array, therefore
isNaN([1,2,3]) = true
Because, as a shorthand in Javascript,, arrays containing only one number are considered castable to the number it contains. You can see this behavior with ==
3 == [3] // returns true
Additionaly, that's also why [0] is a falsy value, whereas [n] with n not zero is a truthy value, an horrible potential source of bugs.
[0] == false // returns true
[1] == false // returns false
So as we know
isNaN([3]) // returns false
A workaround to test number vs array with number
Number([3]) === [3] //returns false
Number(3) === 3 // returns true
Remember that === means matching the values and type

! operator in Javascript - use cases

I'm just starting to learn Javascript, and am using this reference: https://www.discovermeteor.com/blog/javascript-for-meteor/
There's an interesting commentary that I can't get my head around. I quote below.
An interesting consequence of the ! operator is that it always returns a boolean value, even if what comes after is not a boolean:
a = 12;
!a; // false
This means that if you want to convert a variable to boolean you can just use the ! operator twice (once to force the variable to boolean, a second time to revert the value back):
a = 12;
!!a; // true
Or:
a = 0;
!!a; // false
Can anyone help me makes sense of the wording?
Is it simply trying to say that any integer other than 0 gets assigned a Boolean value of True, and that you can return a Boolean value of True/False by using "!" and "!!" respectively?
Yes, !!something is a way to convert something into a boolean (essentially finding out whether something is truthy). 0 and NaN are the only number values that would convert to false with the !! operator (or Boolean() call). All other numbers will be true.
Similarly, +something is a way to convert something into a number.
I usually prefer the more explicit approach: Boolean(something) and Number(something).

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 possible avoid internal number conversion on isNaN() function in JavaScript?

As the title of the question says, I want to avoid the internal number conversion on the isNaN() function.
isNaN() function try to convert the input parameter to a number calling to the Number() function.
For example, if a user puts a value false in an input text who is tested with the isNaN() function to see if the input data is "not a number", the result will be "false", because the Number() function performs a conversion of the value false to 0.
So, it's possible do this? For example, using a pragma or something?
Thanks!
The Number.isNaN() function works differently than the global isNaN(). Number.isNaN() performs no type coercion.
Now, it's important to understand what the concept NaN means. It does not simply mean, "something that is not a number". It's about the floating point system, and specifically about values that don't mean anything. If you want to check whether some unknown value is a number, there are better ways of doing it. The isNaN functions are really about numerics.
A simple test:
function isNumberReally( n ) {
return n === Number(n);
}
That uses the Number constructor to perform a conversion (if it can). It then checks to see whether the result compares as equal to the original using the no-conversions === operator. Only true primitive numbers pass that test; a string like "123" will not.
There really isn't a way to stop isNan from type conversion; Javascript does this automatically. However, you can try to create a a new Number() from the string of what you want to check, like this:
var a=false;
isNaN(Number(String(a)));//returns true;
Or you can check if something equals its number equivalent, like
return num===Number(num);
which basically does not convert types when checking equivalence.
In case you are open to other things, you could always use typeof num==="number";
The isNaN function only works reliably on something that is already a number type. If you give it any other type, it will give results that are not consistent with what you might naturally expect.
Parse the string to a number, then you can use the isNaN function on it. The parsing can either result in a number or the value NaN (which is also of the type number), and isNaN can give you a consistent result from that. Example:
if (isNaN(parseFloat(textbox.value))) {
alert('oops');
}
Note however, that the parsing will happily parse only part of the value. If someone enters a value like 123abc, the parseFloat call will return the number 123.
If you want the input to contain only a number and nothing else, you would need to verify it. For example using a regular expression that only accepts digits:
if (/^\d+$/.test(textbox.value)) {
alert("fine");
}

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

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

Categories