parseInt vs unary plus – 何时使用哪个

这一行之间有什么区别:

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

和这一行

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

这个jsperftesting表明,一元运算符在当前chrome版本中快得多,假设它是为node.js !?

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

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

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

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

请查看此答案以获得更完整的一组案例




那么,以下是我所知道的一些差异:

  • 一个空string""评估为0 ,而parseInt评估它为NaN 。 海事组织,一个空白的string应该是一个NaN

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

    另一方面, parseInt在看到一个非数字字符(如打算成为小数点的句点)时会停止parsing.

     +'2.3' === 2.3; //true parseInt('2.3',10) === 2; //true 
  • parseIntparseFloatparsing并build立从左到右的string。 如果他们看到一个无效的字符,它会将已parsing(如果有的话)作为数字返回,如果没有parsing成数字,则返回NaN

    如果整个string不可转换为数字,则一元组+将返回NaN

     parseInt('2a',10) === 2; //true parseFloat('2a') === 2; //true isNan(+'2a'); //true 
  • 如@Alex K.的评论所示, parseIntparseFloat将按字符进行parsing。 这意味着hex和指数符号将失败,因为xe被视为非数字组件(至less在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. 

最终的任意数字转换表: 在这里输入图像说明

 EXPRS = [ 'parseInt(x)', 'parseFloat(x)', 'Number(x)', '+x', '~~x', 'x>>>0' ]; 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', '[].undef', '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 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 } 

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

  • Unary plus并不把所有的Falsy值都视为相同的,但是他们都是出于谬误。
  • 一元加号发送到1,但是对于NaN "true"
  • 另一方面,对于不是纯数字的string, parseInt更为自由。 parseInt('123abc') === 123 ,而+报告NaN
  • Number将接受有效的十进制数字,而parseInt只会丢弃小数点后的所有内容。 因此, parseInt模仿C的行为,但可能不是评估用户input的理想select。
  • 都修剪string中的空白。
  • parseInt是一个devise不好的parsing器 ,可以接受八进制和hexinput。 一元加只需要hex。

将Falsy值转换为Number后面的内容在C中有意义: nullfalse都为零。 "" 0”并不完全遵循这个约定,但对我来说意义重大。

因此,我认为,如果你正在validation用户input,一元加法除了接受小数(除了在我的真实生活中我更感兴趣的是抓取电子邮件input而不是userId,完全省略值等) parseInt太自由了。

要小心,parseInt比Node.JS中的+一元运算符更快,这是错误的,+或| 0更快,只有NaN元素更快。

看一下这个:

 var arg=process.argv[2]; rpt=20000; mrc=1000; a=[]; b=1024*1024*1024*1024; for (var i=0;i<rpt;i++) a[i]=Math.floor(Math.random()*b)+' '; t0=Date.now(); if ((arg==1)||(arg===undefined)) for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) { c=a[i]-0; } t1=Date.now(); if ((arg==2)||(arg===undefined)) { for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) { d=a[i]|0; } } t2=Date.now(); if ((arg==3)||(arg===undefined)) { for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) { e=parseInt(a[i]); } } t3=Date.now(); if ((arg==3)||(arg===undefined)) { for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) { f=+a[i]; } } t4=Date.now(); console.log(a[i-1],c,d,e,f); console.log('Eseguiti: '+rpt*mrc+' cicli'); console.log('parseInt '+(t3-t2)); console.log('|0 '+(t2-t1)); console.log('-0 '+(t1-t0)); console.log('+ '+(t4-t3)); 

也考虑性能 。 我很惊讶, parseInt击败了iOS上的一元加:)这对于只占用大量CPU的Web应用程序是有帮助的。 作为一个经验法则,我build议JS opt-guys从现在的移动性能angular度考虑任何JS运营商。

所以,先去手机吧