This question already has answers here:
What is the rationale for all comparisons returning false for IEEE754 NaN values?
(12 answers)
Closed 1 year ago.
So, I have the following issue:
let str = "M1"
console.log(parseInt(str.charAt(0)) != NaN))
It says true for some reason. Same with 1M.
As long as I know, NaN is a number type.
Though, I need (parseInt(str.charAt(0)) != NaN) == false in this case. And true in case of 1M.
Thanks for every answer.
PS* parseInt(str) returns NaN
Rather than trying to prove a negative and prove that something is not NaN (remembering that NaN istelf means Not a Number) and expecting a false... too many double negtives
try simply isNaN(str[0])
let str1 = "M1";
let str2 = "1M";
let result1 = isNaN(str1[0]);
let result2 = isNaN(str2[0]);
console.log(result1); // gives true - ie: str1[0] is not a number
console.log(result2); // gives false -ie: str2[0] a number
NaN === NaN is false, so you can't just compare them with === or !==
You can use isNaN(parseInt(str.charAt(0)) instead.
You can't compare NaN with == operator. Easily check it in if:
let str = "M1"
if(!parseInt(str.charAt(0)))
console.log("NaN")
It is working as expected. NaN is global property and is of not type number.
Here parseInt('M1'.charAt(0)) != NaN will be tested as NaN !== NaN. Since NaN is a global object these two NaN are not pointing same object but two different objects. So it is returning true
In second case (parseInt('1M'.charAt(0)) !== NaN), it is obvious true as 1 !== NaN.
Note: Use === instead of ==
Because: NaN is not equal to NaN
let str = "M1"
console.log(parseInt(str.charAt(0)) != NaN))
parseInt(str.charAt(0)) is a NaN value which is not equal to another NaN value.
Check this out NaN - JavaScript | MDN
Related
This question already has answers here:
How do you check that a number is NaN in JavaScript?
(33 answers)
Closed 3 years ago.
I have been trying to check the value and type of NaN for equality but I am getting errors every time. It seems like there must be a simpler solution. Here are four possible solutions I have tried so far that do not work. Another thing is that the underscore in the first solution is not recognized on edabit or codepen:
solution 1
function checkEquality(a, b) {
if((typeof a === typeof b) ||
(_.isNaN(a) === true) &&
(_.isNaN(b) === true)) {
return true;
}
}
solution 2
function checkEquality(a, b) {
let divisionByZod = 42 / "General Zod";
let valueIsNaN = (divisionByZod !== divisionByZod);
if((typeof a === typeof b) || (42 / 'General Zod' === true)) {
return true;
}
}
solution 3
function checkEquality(a, b) {
if(((typeof a === typeof b) || (isNaN(parseInt(NaN))))) {
return true;
}
}
solution 4
function checkEquality(a, b) {
let c = NaN;
if(((typeof a !== typeof b) || (isNaN(parseInt(c) !== NaN)))) {
return false;
}
}
The best option to check if a variable is not a number is the isNan() function.
https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/isNaN
Is good to observe that :
Unlike all other possible values in JavaScript, it is not possible to rely on the equality operators (== and ===) to determine whether a value is NaN or not, because both NaN == NaN and NaN === NaN evaluate to false. Hence, the necessity of an isNaN function.
I don't know your use case but take in consideration that it is not possible to rely on the equality operators (== and ===) to determine whether two objects are equal or not, to this purpose the best is use Object.is() function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
Observe that :
Object.is() determines whether two values are the same value. Two values are the same if one of the following holds:
both undefined
both null
both true or both false
both strings of the same length with the same characters in the same order
both the same object (means both object have same reference)
both numbers and
both +0
both -0
both NaN
or both non-zero and both not NaN and both have the same value
This is not the same as being equal according to the == operator. The == operator applies various coercions to both sides (if they are not the same Type) before testing for equality (resulting in such behavior as "" == false being true), but Object.is doesn't coerce either value.
This is also not the same as being equal according to the === operator. The === operator (and the == operator as well) treats the number values -0 and +0 as equal and treats Number.NaN as not equal to NaN.
Knowing that I think that Object.is(a,b) is the solution for your problem.
const nan1 = 'a string' / 2
const nan2 = 'another string' / 2
const comparation = Object.is(nan1,nan2)
console.log(comparation) // true
if (isNaN(x)) {
return 'Not a Number!';
}
isNaN is the function you are looking for
Try function isNaN(). Returns true if value NaN
Try to use the Object.is() method. It determines whether two values are the same value. Two values are the same if one of the following holds:
both undefined
both null
both true or both false
both strings of the same length with the same characters in the same order
both the same object (means both object have same reference)
both numbers and
both +0
both -0
both NaN
or both non-zero and both not NaN and both have the same value
Refer to the following documentation which
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
I know Lodash often adds some extra checks or niceties to functions that already exist in JavaScript but it's not clear what _.toNumber specifically does that I wouldn't get with parseInt.
I'd prefer to use Lodash only when it provides benefits that aren't there with existing JavaScript functions but I can't see any in this case.
I think it is much better to simply look at the _.toNumber source and that would practically answer your question:
function toNumber(value) {
if (typeof value == 'number') {
return value;
}
if (isSymbol(value)) {
return NAN;
}
if (isObject(value)) {
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
value = isObject(other) ? (other + '') : other;
}
if (typeof value != 'string') {
return value === 0 ? value : +value;
}
value = value.replace(reTrim, '');
var isBinary = reIsBinary.test(value);
return (isBinary || reIsOctal.test(value))
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
: (reIsBadHex.test(value) ? NAN : +value);
}
As you can see it does a bunch of other things in comparison to parseInt. To be more specific:
console.log(_.toNumber(1), parseInt(1)) // same
console.log(_.toNumber('1'), parseInt('1')) // same
console.log(_.toNumber('b'), parseInt('b')) // same
console.log(_.toNumber({}), parseInt({})) // same
console.log(_.toNumber(' 1 '), parseInt(' 1 ')) // same
console.log(_.toNumber([1]), parseInt([1])) // same
console.log(_.toNumber(' 1a1 '), parseInt(' 1a1 ')) // NaN 1
console.log(_.toNumber([1,2]), parseInt([1,2])) // NaN 1
console.log(_.toNumber(false), parseInt(false)) // 0 NaN
console.log(_.toNumber(!0), parseInt(!0)) // 1 NaN
console.log(_.toNumber(!!0), parseInt(!!0)) // 0 NaN
console.log(_.toNumber(5e-324), parseInt(5e-324)) // 5e-324 5
console.log(_.toNumber(5.5), parseInt(5.5)) // 5.5 5
console.log(_.toNumber(null), parseInt(null)) // 0 NaN
console.log(_.toNumber(Infinity),parseInt(Infinity)) // Infinity NaN
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
So to summarize _.isNumber gives you more expected / consistent and I would argue safer results when it comes to parsing input with arrays, decimals, falsy values and strings. It would check the entire input vs parseInt which only cares about the first valid value as you can see from the examples above. It also handles better the negate operator (!) etc.
So overall it does have its uses vs parseInt
Note: What is a gotcha here is that both _.toNumber and parseInt return NaN for undefined which considering how _.toNumber deals with the rest of the falsy values one would expect to return 0 vs NaN:
console.log(_.toNumber(undefined), parseInt(undefined)) // NaN NaN
_.toNumber converts a given input to a number if such a conversion is possible, otherwise returns NaN. The parseInt and parseFloat methods also work in same manner (the former will only return integers though), however, they are much more lax in their parsing rules. _.toNumber is significantly more restrictive.
For eg, with same input '5.2a', parseInt would return 5, parseFloat would return 5.2, and _.toNumber would return NaN. The former two ignore everything after the first unrecognised character and return the number formed by all parsed characters till that point. The last one however returns NaN if an unrecognised character is encountered.
_.toNumber is comparable and functionally same to Number function.
This question already has answers here:
How do you check that a number is NaN in JavaScript?
(33 answers)
Closed 6 years ago.
Is there a best way to prevent NaN? I have number input field that whenever I clear the field, I get NaN.
_amount: function(e) {
var value = parseInt(e.target.value);
var newValue = (value === NaN ? 0 : value); // Thought this could work
},
<input type="number" value={this.state.amount} onChange={this_amount} />
Now in my render I have 400 - this.state.amount. The things is, when I clear the input field, amount state is null. How to prevent this? Is it possible that when I clear the field I get zero? Say I type in 3 then clear the field, NaN pops up.
Thanks
NaNis never equals to anything including NaN itself hence rely on Number.isNaN(value) method.
_amount: function(e) {
var value = parseInt(e.target.value);
var newValue = (isNaN(value) ? 0 : value);
//OR sorthand as `NaN` is falsey
var value = parseInt(e.target.value) || 0;
}
The necessity of an isNaN function
Unlike all other possible values in JavaScript, it is not possible to rely on the equality operators (== and ===) to determine whether a value is NaN or not, because both NaN == NaN and NaN === NaN evaluate to false. Hence, the necessity of an isNaN function.[Ref]
The shortest way I found was
var number = (yourVariable || 0)
Because NaN is a falsey value, this will return 0 whenever yourVariable is NaN.
A way to check, if a number is NaN or not is to use the isNaN function.
isNaN(yourVariable); // Returns true is yourVariable is NaN
Side note:
The above method can be used for multiple problems too. For example: getting a value from an array (wich may not exist) and getting a value from a 2d array.
Getting value from array:
yourArray[i] || 0
Where i is the id you want to access
Getting value from a 2D array:
(yourArray[i] || [])[j] || 0
Where i and j are the position of the element in the array
Saw this in my newsletter. Tested on Chrome and Firefox. I still can't figured it out.
[]+(-~{}-~{}-~{}-~{})+(-~{}-~{}); //=> "42"
Evaluating:
~{}
is evaluated using the internal function:
~ToInt32({})
which gives -1.
Ref ECMA spec - http://www.ecma-international.org/ecma-262/5.1/#sec-9.5
and this explanation - http://jibbering.com/faq/notes/type-conversion/#tcToInt32
Therefore, in this case
(-~{}-~{}) == 2
(-~{}-~{}-~{}-~{}) == 4
As you have []+ in the start of expression, javascript use plus operands like string. So you have "" + "4" + "2" = "42"
The ~ operator is a Bitwise NOT operator. It returns the "1's complement" of a number. Because of that {} is converted into a number, resulting in NaN. The same would happen with +{} == NaN. The bitwise not of ~NaN == -1. So:
(-~{}-~{}-~{}-~{}) == 4 & (-~{}-~{}) == 2
The DefaultValue for an empty array is an empty string. For example []==[]+[] && []+[]==''
From that, the full parsing is:
[]+ /*converted to ''+*/ (-~{}-~{}-~{}-~{}) /*Equals numeric 4, but concatenated as a string to become '4'*/ + (-~{}-~{}) /*Equals numeric 2, but concatenated as a string to become '2'*/ and the end result is actually '42'.
You can validate this via typeof([]+(-~{}-~{}-~{}-~{})+(-~{}-~{})) === 'string'
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Javascript === vs == : Does it matter which “equal” operator I use?
When would JavaScript == make more sense than ===?
What is the difference between below methods in comparing a string with undefined value.
var x;
if(x==undefined)
{
alert(x);
}
and
if(x===undefined)
{
alert(x);
}
Why should i prefer second method in this case.. Please let me know advantages..
== attempts to convert the values to the same type before testing if they're the same. "5" == 5
=== does not do this; it requires objects to be of the same type to be equal. "5" !== 5
In this case, the result is:
x == undefined will be true if x is undefined or null.
x === undefined will only be true if x is undefined.
You should prefer the first method if you'd like undefined and null to be treated equivalently. One common use of this is optional function arguments.
function greet(name, greeting) {
if (name == undefined) name = 'World';
if (greeting == undefined) greeting = 'Hello';
alert(greeting + ' ' + name);
}
greet(); // alerts "Hello World"
greet("Bob"); // alerts "Hello Bob"
greet(null, "Goodbye"); // alerts "Goodbye World"
suppose we have x=5,
== is equal to
x==8 is false
x==5 is true
=== is exactly equal to (value and type)
x===5 is true
x==="5" is false
Hope you understand this concept
=== checks for the same type as well. You'll understand with a few examples:
(1 == '1') //Returns true
Since == doesn't bother with types, that returns true. However, if you want strict type checking, you'd use === because that returns true only if the it's of the same type, and is the same value.
(1 === '1') //Returns false
(1 === 1) //Returns true
Two strings are strictly equal when they have the same sequence of characters, same length, and same characters in corresponding
positions.
Two numbers are strictly equal when they are numerically equal (have the same number value). NaN is not equal to anything,
including NaN. Positive and negative zeros are equal to one another.
Two Boolean operands are strictly equal if both are true or both are false.
Two objects are strictly equal if they refer to the same Object.
Null and Undefined types are == (but not ===).
Reference
== is just comparing the two values, and if they are of different types, type conversion is done
=== compares the values and well as their types - so no type conversion will be done here.