parseInt vs unary plus, when to use which?
The ultimate whatever-to-number conversion table:
EXPRS = [
'parseInt(x)',
'parseFloat(x)',
'Number(x)',
'+x',
'~~x',
'x>>>0',
'isNaN(x)'
];
VALUES = [
'"123"',
'"+123"',
'"-123"',
'"123.45"',
'"-123.45"',
'"12e5"',
'"12e-5"',
'"0123"',
'"0000123"',
'"0b111"',
'"0o10"',
'"0xBABE"',
'"4294967295"',
'"123456789012345678"',
'"12e999"',
'""',
'"123foo"',
'"123.45foo"',
'" 123 "',
'"foo"',
'"12e"',
'"0b567"',
'"0o999"',
'"0xFUZZ"',
'"+0"',
'"-0"',
'"Infinity"',
'"+Infinity"',
'"-Infinity"',
'null',
'undefined',
'true',
'false',
'Infinity',
'NaN',
'{}',
'{valueOf: function(){return 42}}',
'{toString: function(){return "56"}}',
];
//////
function wrap(tag, s) {
if (s && s.join)
s = s.join('');
return '<' + tag + '>' + String(s) + '</' + tag + '>';
}
function table(head, rows) {
return wrap('table', [
wrap('thead', tr(head)),
wrap('tbody', rows.map(tr))
]);
}
function tr(row) {
return wrap('tr', row.map(function (s) {
return wrap('td', s)
}));
}
function val(n) {
return n === true || Number.isNaN(n) ? wrap('b', n) : String(n);
}
var rows = VALUES.map(function (v) {
var x = eval('(' + v + ')');
return [v].concat(EXPRS.map(function (e) {
return val(eval(e))
}));
});
document.body.innerHTML = table(["x"].concat(EXPRS), rows);
table { border-collapse: collapse }
tr:nth-child(odd) { background: #fafafa }
td { border: 1px solid #e0e0e0; padding: 5px; font: 12px monospace }
td:not(:first-child) { text-align: right }
thead td { background: #3663AE; color: white }
b { color: red }
Well, here are a few differences I know of:
-
An empty string
""
evaluates to a0
, whileparseInt
evaluates it toNaN
. IMO, a blank string should be aNaN
.+'' === 0; //true isNaN(parseInt('',10)); //true
-
The unary
+
acts more likeparseFloat
since it also accepts decimals.parseInt
on the other hand stops parsing when it sees a non-numerical character, like the period that is intended to be a decimal point.
.+'2.3' === 2.3; //true parseInt('2.3',10) === 2; //true
-
parseInt
andparseFloat
parses and builds the string left to right. If they see an invalid character, it returns what has been parsed (if any) as a number, andNaN
if none was parsed as a number.The unary
+
on the other hand will returnNaN
if the entire string is non-convertible to a number.parseInt('2a',10) === 2; //true parseFloat('2a') === 2; //true isNaN(+'2a'); //true
-
As seen in the comment of @Alex K.,
parseInt
andparseFloat
will parse by character. This means hex and exponent notations will fail since thex
ande
are treated as non-numerical components (at least on base10).The unary
+
will convert them properly though.parseInt('2e3',10) === 2; //true. This is supposed to be 2000 +'2e3' === 2000; //true. This one's correct. parseInt("0xf", 10) === 0; //true. This is supposed to be 15 +'0xf' === 15; //true. This one's correct.