360

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?

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Joper
  • 8,019
  • 21
  • 53
  • 80
  • 78
    FYI, `NaN != NaN`. You'd need `isNaN(value)`. – pimvdb Jul 18 '11 at 20:55
  • 39
    Yes, no two Nannies are the same ;) – James P. Sep 15 '12 at 02: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. – JonBrave Jan 21 '16 at 10:44

18 Answers18

901
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.

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Matthew
  • 15,464
  • 2
  • 37
  • 31
  • 7
    This won't work if s="4s"; (it returns 4...which is incorrect...) – markzzz Jul 24 '12 at 15:06
  • 1
    parseInt function in js parse any numbers in string – Ali U Apr 07 '13 at 13:20
  • 37
    @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. – trejder Jul 18 '13 at 07:54
  • 3
    @markzzz `var nextIphone = parseInt("4S") + 1; // wow it works!` – Zero Distraction Feb 28 '14 at 00:55
  • This helped me out so much, I couldn't understand why I couldn't solve this. You guys rule... – theGrayFox May 28 '14 at 17:18
  • yeah, I want to return 0, when a value is blank and i want to skip the if statement for every value.. just want to make it simple. this helped me so much. thank you – Vignesh Aug 07 '14 at 11:06
  • 1
    `parseInt(s, 10)` -- 'nuff said – Dexygen Oct 01 '15 at 16:31
  • 3
    @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"**_ – Pablo Recalde Aug 26 '16 at 09:31
  • 1
    hah I tried to upvote this answer for the second time in two years – Dexygen Oct 13 '17 at 20:12
  • @MatthewCaruanaGalizia Correct me if I'm wrong, but isn't that the same way the operator behaves when used with boolean values? – Piyin Jan 23 '18 at 20:52
  • It work for empty string value too! if $('#element').val() equal '' then return 0, Because of $('#element').val() return false even has value! Can you please explain why this happen? I tested return value in https://jsfiddle.net/QMaster/dt8rp6av/ – QMaster Mar 01 '18 at 00:53
  • Excellent answer. Thanks and Appreciate your effort – Ansif Jul 11 '21 at 17:04
60

You can also use the isNaN() function:

var s = ''
var num = isNaN(parseInt(s)) ? 0 : parseInt(s)
Glavić
  • 42,781
  • 13
  • 77
  • 107
gprasant
  • 15,589
  • 9
  • 43
  • 57
  • 13
    Why call `parseInt(s)` twice? Furthermore it should be `parseInt(s, 10)` – Dexygen Oct 01 '15 at 16:32
  • 3
    @GeorgeJempty A radix of "10" is default; that parameter is optional. Good point on calling `parseInt()` twice though. – Autumn Leonard Apr 08 '16 at 18:31
  • 14
    @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 http://stackoverflow.com/questions/8763396/javascript-parseint-with-leading-zeros – chuck258 May 02 '16 at 05:14
29

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
sqren
  • 22,833
  • 7
  • 52
  • 36
  • 2
    Please send a radix to parseInt: `parseInt(string, radix)`, consider this: `parseInt("0x10") === 16` Also `parseInt("010")` could yield `8` in some browsers – Andreas Louv Nov 23 '15 at 20:27
  • 2
    If you're already depending on lodash for other stuff, there's a handy [`defaultTo`](https://lodash.com/docs/4.17.11#defaultTo) function that does just this: `_.defaultTo(NaN, -1)` returns `-1`, but `_.defaultTo(0, -1);` returns `0`. – waldyrious Dec 06 '18 at 12:40
  • 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!) – JonathanDavidArndt May 31 '19 at 15:16
  • Surely you should use a const instead of calling `parseInt` twice – Kyle Delaney Apr 16 '20 at 22:50
26

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.

Roy M J
  • 6,926
  • 7
  • 51
  • 78
Chris Werner
  • 1,286
  • 12
  • 6
10

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)

Ahmad Ibrahim
  • 1,915
  • 2
  • 15
  • 32
9

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
PirateApp
  • 5,433
  • 4
  • 57
  • 90
  • 1
    Very compact. What a shame that you didn't get more points. I voted you up. Please reciprocate to try to catch my -2 acquired today by a mute troll... (see my answer at the end of this page). Thank you. – Fabien Haddadi Aug 16 '18 at 08:41
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
Ankur
  • 2,171
  • 23
  • 29
pimvdb
  • 151,816
  • 78
  • 307
  • 352
  • 15
    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. – jamesmortensen Mar 11 '12 at 00:41
  • 2
    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. – Samuel Sep 11 '12 at 12:43
2
var value = isNaN(parseInt(tbb)) ? 0 : parseInt(tbb);
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
Milap Jethwa
  • 471
  • 4
  • 7
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
  • Can you explain this solution? – RamenChef Nov 13 '16 at 20:28
  • if u want to convert any number (like'123' or 123) to integer, if you will use parseInt('abc') , – AbdulRahman AlShamiri Nov 13 '16 at 20:49
  • if you will use parseInt('abc') u will get to NaN but this function will convert the NaN to 0 – AbdulRahman AlShamiri Nov 13 '16 at 20:51
  • 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`.) – goodeye Nov 26 '16 at 22:57
2

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

Marcos Mendes
  • 1,091
  • 1
  • 8
  • 15
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
bob
  • 7,539
  • 2
  • 46
  • 42
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
Mike
  • 1,525
  • 1
  • 14
  • 11
1
// 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');

Fabien Haddadi
  • 1,814
  • 17
  • 22
1

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

var a="bcd";
~~parseInt(a);
Bishal Gautam
  • 380
  • 3
  • 16
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

Schroedingers Cat
  • 3,099
  • 1
  • 15
  • 33
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?

Paritosh
  • 11,144
  • 5
  • 56
  • 74
NARESH RAMINI
  • 33
  • 1
  • 7
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
Darrel K.
  • 1,611
  • 18
  • 28
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;
}
Jerome Diaz
  • 1,746
  • 8
  • 15