374

Is it possible somehow to return 0 instead of NaN when parsing values in JavaScript?

In case of the empty string parseInt returns NaN.

Is it possible to do something like that in JavaScript to check for NaN?

var value = parseInt(tbb) == NaN ? 0 : parseInt(tbb)

Or maybe there is another function or jQuery plugin which may do something similar?

3
  • 81
    FYI, NaN != NaN. You'd need isNaN(value). Commented Jul 18, 2011 at 20:55
  • 42
    Yes, no two Nannies are the same ;) Commented Sep 15, 2012 at 2:35
  • 3
    Calling function parseInt() twice (in the successful/normal non-NaN case) is never a good idea. Apart from inefficiency, for the unwary if whatever is passed for tbb is a function call with side-effects it is terrible. I would not use any solution here where I see parseInt() twice. Commented Jan 21, 2016 at 10:44

18 Answers 18

938
var s = '';
var num = parseInt(s) || 0;

When not used with boolean values, the logical OR || operator returns the first expression parseInt(s) if it can be evaluated to true, otherwise it returns the second expression 0. The return value of parseInt('') is NaN. NaN evaluates to false, so num ends up being set to 0.

Sign up to request clarification or add additional context in comments.

13 Comments

This won't work if s="4s"; (it returns 4...which is incorrect...)
@markzzz Read question again. OP asks: "Is it possible somehow to return 0 instead of NaN". OP don't want to check, whether particular string is parsable to int. OP wants to get 0 instead of NaN. This is solved by Matt's code perfectly.
@markzzz var nextIphone = parseInt("4S") + 1; // wow it works!
@Matthew please use the terms "falsy" or "truthy". because NaN === false is false! but Boolean(NaN) === Boolean(false) is true. the logical OR returns the first expression if it can be evaluated to "truthy"
hah I tried to upvote this answer for the second time in two years
|
60

You can also use the isNaN() function:

var s = ''
var num = isNaN(parseInt(s)) ? 0 : parseInt(s)

3 Comments

Why call parseInt(s) twice? Furthermore it should be parseInt(s, 10)
@GeorgeJempty A radix of "10" is default; that parameter is optional. Good point on calling parseInt() twice though.
@AutumnLeonard this is only kind of true. If your string starts with a 0 is assumes the number is in octal format so parseInt('077') gives you 63. This can lead to very nasty to find bugs so you should always specify the second parameter. see for example stackoverflow.com/questions/8763396/…
33

The problem

Other answers don't take into account that 0 is falsy, and thus the following will be 20 instead of 0:

const myNumber = parseInt('0') || 20; // 20

The solution

I propose a helper function, that solves most of the issues:

function getNumber({ value, defaultValue }) {
  const num = parseInt(value, 10);
  return isNaN(num) ? defaultValue : num;
}

The helper function will give the following results:

getNumber({ value: "0", defaultValue: 20 }); // 0
getNumber({ value: "2", defaultValue: 20 }); // 2
getNumber({ value: "2.2", defaultValue: 20 }); // 2
getNumber({ value: "any string", defaultValue: 20 }); // 20
getNumber({ value: undefined, defaultValue: 20 }); // 20
getNumber({ value: null, defaultValue: 20 }); // 20
getNumber({ value: NaN, defaultValue: 20 }); // 20
getNumber({ value: false, defaultValue: 20 }); // 20
getNumber({ value: true, defaultValue: 20 }); // 20

4 Comments

Please send a radix to parseInt: parseInt(string, radix), consider this: parseInt("0x10") === 16 Also parseInt("010") could yield 8 in some browsers
If you're already depending on lodash for other stuff, there's a handy defaultTo function that does just this: _.defaultTo(NaN, -1) returns -1, but _.defaultTo(0, -1); returns 0.
This is an excellent point! You can only rely on the || at the end to provide the correct default when your preferred default is ZERO (granted, this is what the OP wanted). As you have mentioned, due to the falsy nature of the '0' input, it is treated as invalid input in this case, and the statement will return the default value instead (maybe not what was expected!)
Surely you should use a const instead of calling parseInt twice
27

I was surprised to not see anyone mention using Number(). Granted it will parse decimals if provided, so will act differently than parseInt(), however it already assumes base 10 and will turn "" or even " " in to 0.

4 Comments

Yes, very handy for reading from localStorage: Number(localStorage.getItem('appBanner.count')) + 1
While that works for the question as it was asked, it still returns NaN for non-number non-whitespace characters
Thanks it worked on first try. Looking around for 15 minutes now :)
+string will do the work, that simple. e.g. +'2' or +'23.2'
11

For people who are not restricted to parseInt, you can use the bitwise OR operator (which implicitly calls ToInt32 to its operands).

var value = s | 0;

// NaN | 0     ==>> 0
// ''  | 0     ==>> 0
// '5' | 0     ==>> 5
// '33Ab' | 0  ==>> 0
// '0x23' | 0  ==>> 35
// 113 | 0     ==>> 113
// -12 | 0     ==>> -12
// 3.9 | 0     ==>> 3

Note: ToInt32 is different from parseInt. (i.e. parseInt('33Ab') === 33)

2 Comments

But: '10000000000' | 0 === 1410065408.
@trincot yes, any value >= Math.pow(2, 31) will overflow.
10

Does the job a lot cleaner than parseInt in my opinion, Use the +operator

var s = '';
console.log(+s);

var s = '1024'
+s
1024

s = 0
+s
0

s = -1
+s
-1

s = 2.456
+s
2.456

s = ''
+s
0

s = 'wtf'
+s
NaN

1 Comment

2.456 is not an int ??
3

Why not override the function? In that case you can always be sure it returns 0 in case of NaN:

(function(original) {
    parseInt = function() {
        return original.apply(window, arguments) || 0;
    };
})(parseInt);

Now, anywhere in your code:

parseInt('') === 0

2 Comments

Overriding the function like this could confuse expert JavaScript programmers who might see that as a bug. Your overridden function is likely to be buried somewhere where it's not likely to be seen. This is creative, but I'm not sure I would personally recommend it considering how easy it is to just add a || 0 as in Matt's answer. I see overriding objects you don't own as a last resort or when not doing so would cost significantly higher in terms of time and complexity.
I'm agree with @jmort253... It's dangerous because the function is too much smart. It's better to do exactly the same function but with a name like getSafeNumberValue or something like that.
3

For other people looking for this solution, just use: ~~ without parseInt, it is the cleanest mode.

var a = 'hello';
var b = ~~a;

If NaN, it will return 0 instead.

OBS. This solution apply only for integers

Comments

2
var value = isNaN(parseInt(tbb)) ? 0 : parseInt(tbb);

Comments

2
//////////////////////////////////////////////////////
function ToInt(x){x=parseInt(x);return isNaN(x)?0:x;}
//////////////////////////////////////////////////////
var x = ToInt('');   //->  x=0
    x = ToInt('abc') //->  x=0
    x = ToInt('0.1') //->  x=0
    x = ToInt('5.9') //->  x=5
    x = ToInt(5.9)   //->  x=5
    x = ToInt(5)     //->  x=5

4 Comments

Can you explain this solution?
if u want to convert any number (like'123' or 123) to integer, if you will use parseInt('abc') ,
if you will use parseInt('abc') u will get to NaN but this function will convert the NaN to 0
Bingo, as the explicit alternative to the || approach. I know this is an old question and answer, but this answer avoids calling parseInt twice, and uses isNaN correctly. It just needs the radix parseInt(x, 10) to be thorough. (My preference is a separate internal variable instead of reusing x.)
2

You can have very clean code, i had similar problems and i solved it by using :

var a="bcd";
~~parseInt(a);

Comments

1

Do a separate check for an empty string ( as it is one specific case ) and set it to zero in this case.

You could appeand "0" to the start, but then you need to add a prefix to indicate that it is a decimal and not an octal number

2 Comments

so you think it is better to append 0 if empty?
No - that is an approach I have used. In this case, a separate check woudl be better. However if Matts solution works, that is even cleaner.
1

I had a similar problem (firefox v34) with simple strings like:

var myInt = parseInt("b4");

So I came up with a quick hack of:

var intVal = ("" + val).replace(/[^0-9]/gi, "");

And then got all stupid complicated to deal with floats + ints for non-simple stuff:

var myval = "12.34";

function slowParseNumber(val, asInt){
    var ret = Number( ("" + val).replace(/[^0-9\.]/gi, "") );
    return asInt ? Math.floor(ret) : ret;
}
var floatVal = slowParseNumber(myval);

var intVal = slowParseNumber(myval, true);
console.log(floatVal, intVal);

It will return 0 for things like:

var intVal = slowParseNumber("b"); // yeilds 0

Comments

1

I created a 2 prototype to handle this for me, one for a number, and one for a String.

// This is a safety check to make sure the prototype is not already defined.
Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
        return this;
    }
};

// returns the int value or -1 by default if it fails
Number.method('tryParseInt', function (defaultValue) {
    return parseInt(this) == this ? parseInt(this) : (defaultValue === undefined ? -1 : defaultValue);
});

// returns the int value or -1 by default if it fails
String.method('tryParseInt', function (defaultValue) {
    return parseInt(this) == this ? parseInt(this) : (defaultValue === undefined ? -1 : defaultValue);
});

If you dont want to use the safety check, use

String.prototype.tryParseInt = function(){
    /*Method body here*/
};
Number.prototype.tryParseInt = function(){
     /*Method body here*/
};

Example usage:

var test = 1;
console.log(test.tryParseInt()); // returns 1

var test2 = '1';
console.log(test2.tryParseInt()); // returns 1

var test3 = '1a';
console.log(test3.tryParseInt()); // returns -1 as that is the default

var test4 = '1a';
console.log(test4.tryParseInt(0));// returns 0, the specified default value

Comments

0

Also this way, why not write a function and call it where ever required . I'm assuming it's the entry into the form fields to perform calculations.

var Nanprocessor = function (entry) {
    if(entry=="NaN") {
        return 0;
    } else {
        return entry;
    }
}

 outputfield.value = Nanprocessor(x); 

// where x is a value that is collected from a from field
// i.e say x =parseInt(formfield1.value); 

what's wrong doing this?

3 Comments

Hi,wat's stopping us from following above method. Would like to know n learn.
You should use isNaN to test for NaN.
Thanks Matt :) I don't know that there's a function called isNaN() in javascrip! Thanks for letting me know...!
0

Here is a tryParseInt method that I am using, this takes the default value as second parameter so it can be anything you require.

function tryParseInt(str, defaultValue) {
    return parseInt(str) == str ? parseInt(str) : defaultValue;
}

tryParseInt("", 0);//0 
tryParseInt("string", 0);//0 
tryParseInt("558", 0);//558

Comments

0

an helper function which still allow to use the radix

function parseIntWithFallback(s, fallback, radix) {
    var parsed = parseInt(s, radix);
    return isNaN(parsed) ? fallback : parsed;
}

Comments

0
// implicit cast
var value = parseInt(tbb*1); // see original question

Explanation, for those who don't find it trivial:

Multiplying by one, a method called "implicit cast", attempts to turn the unknown type operand into the primitive type 'number'. In particular, an empty string would become number 0, making it an eligible type for parseInt()...

A very good example was also given above by PirateApp, who suggested to prepend the + sign, forcing JavaScript to use the Number implicit cast.

Aug. 20 update: parseInt("0"+expr); gives better results, in particular for parseInt("0"+'str');

4 Comments

It is a direct answer to the original question my Dear.
This won't do for parseInt('str'*1)
Why call parseInt on something that is already a number? That will incur yet another conversion back to string only to convert that to number again.
trincot: that's for cases when you're not 100% sure you'll deal with an integer operand, obviously.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.