parseInt vs unary plus,什么时候使用哪个?

2022-08-30 01:36:04

这条线有什么区别:

var a = parseInt("1", 10); // a === 1

和这条线

var a = +"1"; // a === 1

这个jsperf测试表明,在当前的chrome版本中,一元运算符要快得多,假设它是针对node.js!?

如果我尝试转换不是数字的字符串,则两者都返回:NaN

var b = parseInt("test" 10); // b === NaN
var b = +"test"; // b === NaN

因此,我什么时候应该更喜欢使用一元加号(特别是在node.js)???parseInt

编辑:与双波浪号运算符有什么区别?~~


答案 1

终极的任意数字转换表: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"',
    'BigInt(1)',

    '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) || n === "Error" ? wrap('b', n) : String(n);
}

var rows = VALUES.map(function (v) {
    var x = eval('(' + v + ')');
    return [v].concat(EXPRS.map(function (e) {
        try {
            return val(eval(e));
        } catch {
            return val("Error");
        }
    }));
});

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 }

答案 2

好吧,以下是我知道的一些差异:

  • 空字符串的计算结果为 ,而计算结果为 。IMO,空白字符串应为 .""0parseIntNaNNaN

      +'' === 0;              //true
      isNaN(parseInt('',10)); //true
    
  • 一元的行为更像,因为它也接受小数。+parseFloat

    parseInt另一方面,当它看到非数字字符时停止解析,例如旨在成为小数点的句点 。.

      +'2.3' === 2.3;           //true
      parseInt('2.3',10) === 2; //true
    
  • parseInt并解析并构建从左到右的字符串。如果他们看到无效字符,它将返回已解析为数字的内容(如果有),如果没有被解析为数字。parseFloatNaN

    另一方面,如果整个字符串不可转换为数字,则一元将返回。+NaN

      parseInt('2a',10) === 2; //true
      parseFloat('2a') === 2;  //true
      isNaN(+'2a');            //true
    
  • @Alex K.的评论所示,并将按字符解析。这意味着十六进制和指数表示法将失败,因为 和 被视为非数值分量(至少在 base10 上)。parseIntparseFloatxe

    不过,一元会正确地转换它们。+

      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.