parseInt vs unary plus - 何时使用哪个

her*_*w78 135 javascript node.js

这一行有什么区别:

var a = parseInt("1", 10); // a === 1
Run Code Online (Sandbox Code Playgroud)

这条线

var a = +"1"; // a === 1
Run Code Online (Sandbox Code Playgroud)

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

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

var b = parseInt("test" 10); // b === NaN
var b = +"test"; // b === NaN
Run Code Online (Sandbox Code Playgroud)

那么我什么时候应该优先使用parseInt一元加(尤其是在node.js中)???

编辑:双波浪运算符的区别是什么~~

geo*_*org 238

最终的无数转换表: 在此输入图像描述

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);
Run Code Online (Sandbox Code Playgroud)
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 }
Run Code Online (Sandbox Code Playgroud)

  • 所以,表格的总结是`+`只是写`Number`的一种更短的方式,而更远的只是在边缘情况下失败的疯狂方式? (7认同)
  • 请在此表中添加`"NaN"`。 (4认同)
  • 可能值得向这个表添加一个 `isNaN` 列:例如,`isNaN("")` 是假的(即它被认为是一个数字),但是 `parseFloat("")` 是 `NaN`,它可以是一个问题,如果你在将输入传递给 `parseFloat` 之前尝试使用 `isNaN` 来验证输入 (2认同)
  • 您还应该将 `'{valueOf: function(){return 42}, toString: function(){return "56"}}'` 添加到列表中。混合的结果很有趣。 (2认同)

Jos*_*eph 157

请查看此答案以获取更完整的案例集




嗯,这里有一些我所知道的差异:

  • 空字符串""计算为a 0,同时将其parseInt计算为NaN.IMO,一个空字符串应该是一个NaN.

    +'' === 0;              //true
    isNaN(parseInt('',10)); //true
    
    Run Code Online (Sandbox Code Playgroud)
  • 一元+行为更像是parseFloat因为它也接受小数.

    parseInt另一方面,当它看到一个非数字字符时停止解析,比如想要成为小数点的句点..

    +'2.3' === 2.3;           //true
    parseInt('2.3',10) === 2; //true
    
    Run Code Online (Sandbox Code Playgroud)
  • parseInt从左到右parseFloat分析和构建字符串.如果他们看到一个无效字符,它会将已解析的内容(如果有)作为数字返回,如果没有被解析为数字.NaN

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

    parseInt('2a',10) === 2; //true
    parseFloat('2a') === 2;  //true
    isNan(+'2a');            //true
    
    Run Code Online (Sandbox Code Playgroud)
  • 正如@Alex K.的评论中所见,parseInt并将parseFloat按字符解析.这意味着十六进制和指数表示法将失败,因为xe被视为非数字组件(至少在base10上).

    一元+将会正确地转换它们.

    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.
    
    Run Code Online (Sandbox Code Playgroud)

  • 当使用基数"+"0xf"!= parseInt("0xf",10)`时 (6认同)
  • 实际上,`"2e3"`不是`2000`的有效整数表示.它是一个有效的浮点数:`parseFloat("2e3")`将正确地产生`2000`作为答案.并且`"0xf"`至少需要16位,这就是为什么`parseInt("0xf",10)`返回`0`,而`parseInt("0xf",16)`返回你期望的15的值. (4认同)
  • @Joseph the the Dreamer和@ hereandnow78:Double tilde切断数字的小数部分,而Math.floor返回最接近的数字.它们的正数相同,但是`Math.floor(-3.5)== -4`和`~~ -3.5 == -3`. (2认同)

dje*_*lin 10

我认为thg435的答案中的表格是全面的,但我们可以用以下模式总结:

  • 一元加上不会对所有的假值都一致,但它们都是假的.
  • 一元加发true1,但"true"NaN.
  • 另一方面,parseInt对于不是纯数字的字符串更自由. parseInt('123abc') === 123+报告NaN.
  • Number将接受有效的十进制数,而parseInt只是删除小数点后的所有内容.因此parseInt模仿C行为,但可能不是评估用户输入的理想选择.
  • 两者都修剪字符串中的空白.
  • parseInt,作为一个设计糟糕的解析器,接受八进制和十六进制输入.一元加只需要十六进制.

Falsy值转换为Number跟随C:有意义的值, null并且false都是零. ""转到0并不完全遵循这个惯例,但对我来说足够了.

因此,我认为如果您正在验证用户输入,一元加上除了接受小数之外的所有内容都有正确的行为(但在我的现实生活中,我更感兴趣的是捕获电子邮件输入而不是userId,值完全省略等),而parseInt太自由了.

  • “一元加法只取十六进制”你不是说十进制吗? (4认同)