开发者

How to turn NaN from parseInt into 0 for an empty string?

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

I开发者_开发知识库n 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?


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.


You can also use the isNaN() function:

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


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


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.


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)


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


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


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


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


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


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


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


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


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

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


// 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');


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?


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


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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜