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

Related

Calling a JavaScript function that returns a Boolean

* EDITED *
REF: Calling a JavaScript function that returns a Boolean [on hold]
function booleanFunction()
{
if (something) return true;
else return false;
}
My original question was "When calling a Boolean Function, is it correct to say?":
if (booleanFunction)
or
if (booleanFunction())
I had previously read that the first choice was correct. Your voluminous responses said otherwise.
Based on all that I have learned from all your responses, I conclude:
(1) if (booleanFunction) is truthy in the sense that this if statement will ALWAYS return true. In other words, this if statement is equivalent to asking if this booleanFunction EXISTS, independent of its correctness.
(2) to evaluate the value (true or false) returned by the booleanFunction, I need to say if (booleanFunction()).
Have I concluded correctly?
The text you quote is outright incorrect.
To call a function, use parentheses. If the function takes no arguments, the call looks like booleanFunction() and returns a value.
To evaluate a value, put it into parentheses. In an if-statement, while-loop, a value is converted to a boolean automatically, the same as (new Boolean( SOME_VALUE )).valueOf() or !! (SOME_VALUE). Refer to MDN for the full conversion rules. For instance,
if (booleanFunction()) {
is perfectly fine, but
if (booleanFunction) {
would convert the value of booleanFunction to boolean, and that is true, because any function object will be converted to true.
I have edited my original question. Hopefully, it is now totally clear.

! 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 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

javascript why isNaN(new Date()) is false

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.

Is it incorrect to use eval() within this function? Can I accomplish the same functionality without it somehow?

I'm trying to write a function I can use to test all for falsy values, keeping it concise since it will be run quite often serverside.
function is_falsy(val){
val = eval(String(val).toLowerCase());
return !!val;
}
I wonder if there's any way it could be done shorter, or what the possible negative implications of using eval() might be. JSBIN tells me it is "evil".
JSBIN
Assuming that val is a string that represents a JavaScript literal then we can take advantage of the fact that the only false-y values in JavaScript are:
0 (+ or -)
NaN
the empty string ('') or ("")
null
undefined
false
Thus, ignoring edge-cases (like 0.0) we could write it like so (a lower case can be performed as in the original code):
function is_falsey_literal (lit) {
if (['""', "''", "null", "undefined", "false", "0", "NaN"].indexOf(lit) >= 0) {
return true;
}
// Ideally there are more checks on numeric literals such as `-0` or `0.0`.
return false;
}
If needing to check a full expression then eval may "work" and is likely more practical when compared to writing a full JavaScript-in-JavaScript parser. For instance, in the above, the input string of (void 0) will be "true" although it evaluates to undefined which is definitely not a truth-y value.
Of course, perhaps the original data can be written/consumed such that there is no need for such a construct at all ..
There should never be any need to treat a string containing false or undefined as falsy. Doing so is inviting false positives (or false negatives) on possibly completely unrelated data.
Imagine what else would be treated as "falsy":
!true
!1
!!true
it's begging for mysterious bugs in your application further down the line.
The program flow should make sure that an undefined value actually arrives at your testing script as a literal undefined, not a string "undefined".
If you only want to test is falsy, then the below is enough.
function is_falsy(val){
return !val;
}
If you want to test whether a string is falsy value like 'false', then
function is_falsy(val){
try {
return !JSON.parse(String(val).toLowerCase());
} catch(e) {
return false;
}
}

Categories