I have not been able to write anything in my blog for about a couple of months. I admit that I have been really very busy with my project (with ample of learning opportunities ). And today what I am going to write about ,is something that I did learn these days, working on that project.
Well last week I found that one of the condition check in my JavaScript code was letting an invalid value to pass. By invalid I mean a value which was expected to fail the conditional "check and hence the code inside the "if " statement should not get executed. It was a really very simple check with no calculation involved in it at all.
The conditional check was supposed to allow only numeric values. And the check was done using JavaScript function "isNaN()".
The "isNaN()" function determines whether a value is an illegal number (Not-a-Number). It returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).
This function returns true if the value is NaN, and false if not.
So far so good.
Well last week I found that one of the condition check in my JavaScript code was letting an invalid value to pass. By invalid I mean a value which was expected to fail the conditional "check and hence the code inside the "if " statement should not get executed. It was a really very simple check with no calculation involved in it at all.
The conditional check was supposed to allow only numeric values. And the check was done using JavaScript function "isNaN()".
The "isNaN()" function determines whether a value is an illegal number (Not-a-Number). It returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).
This function returns true if the value is NaN, and false if not.
So far so good.
if(!isNaN(value)){
// gets executed only if the value is a number
// some method calls
}else{
// some other code
}
// gets executed only if the value is a number
// some method calls
}else{
// some other code
}
And I thought I was literally using a correct function to allow only numeric values, until when performing unit testing using KarmaJs, for my code , I found that some unexpected things are actually going on inside the conditional check which resulted in exceptions .
Now I started to debug, and soon I realized that the function "isNan(value)" doesnot only return false for numeric values but rather it returns false for any value which "it can convert to a mathematical number".
What was going wrong in my code was that "isNaN(value) was returning false" when the value was boolean(true or false). As a result boolean values were able to make a way to get inside the code which was not meant for them .
After doing some research on it I came up with the information that,
Now I started to debug, and soon I realized that the function "isNan(value)" doesnot only return false for numeric values but rather it returns false for any value which "it can convert to a mathematical number".
What was going wrong in my code was that "isNaN(value) was returning false" when the value was boolean(true or false). As a result boolean values were able to make a way to get inside the code which was not meant for them .
After doing some research on it I came up with the information that,
Only if the value is not a number or "cannot be converted to a number" ,the isNaN() function returns true. Otherwise it returns false.
See here the problem was boolean "true" coerces to 1 and boolean "false" coerces to 0 and the isNaN () then treated them as numeric returning false for them.
Even though during unit testing the piece of code written by me , failed only for the boolean values, but I admit the truth is that, it certainly would have failed if the value passed were either "null" or an empty string!!!
Let me elaborate more on this - If the value being evaluated is null or an empty string, isNaN returns false because both null and empty string evaluate to 0.
And there I realized that I was making a very big mistake by writing such a crap code!!!!
Few things which you certainly ought to know about isNaN() are:
Even though during unit testing the piece of code written by me , failed only for the boolean values, but I admit the truth is that, it certainly would have failed if the value passed were either "null" or an empty string!!!
Let me elaborate more on this - If the value being evaluated is null or an empty string, isNaN returns false because both null and empty string evaluate to 0.
And there I realized that I was making a very big mistake by writing such a crap code!!!!
Few things which you certainly ought to know about isNaN() are:
isNaN(" "); // false, a empty string coerces to zero
isNaN("\n\t"); // false, a white-space string coerces to zero
isNaN(true); // false, boolean true coerces to 1
isNaN(false); // false, boolean false coerces to zero
isNaN(new Date()); // false, Date objects coerce to its numeric timestamp
isNaN(null)// null eveluates to 0
// etc...
isNaN("\n\t"); // false, a white-space string coerces to zero
isNaN(true); // false, boolean true coerces to 1
isNaN(false); // false, boolean false coerces to zero
isNaN(new Date()); // false, Date objects coerce to its numeric timestamp
isNaN(null)// null eveluates to 0
// etc...
Now the question was how do I improve my code and do the number type testing.
function isNumber(value) {
return typeof value === 'number' && isFinite(value);
}
return typeof value === 'number' && isFinite(value);
}
However remember if you wish to treat "1" as a valid number then the above function will not allow you to do so.
In that case you may use the following function definition instead.
In that case you may use the following function definition instead.
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
return !isNaN(parseFloat(n)) && isFinite(n);
}
Happy Coding :)
Reference: Mozilla Developers Network
The Problem for Testing for NaN in JavaScript
Reference: Mozilla Developers Network
The Problem for Testing for NaN in JavaScript