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
-
parseInt
和parseFloat
parsing并build立从左到右的string。 如果他们看到一个无效的字符,它会将已parsing(如果有的话)作为数字返回,如果没有parsing成数字,则返回NaN
。如果整个string不可转换为数字,则一元组
+
将返回NaN
。parseInt('2a',10) === 2; //true parseFloat('2a') === 2; //true isNan(+'2a'); //true
-
如@Alex K.的评论所示,
parseInt
和parseFloat
将按字符进行parsing。 这意味着hex和指数符号将失败,因为x
和e
被视为非数字组件(至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中有意义: null
和false
都为零。 ""
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运营商。
所以,先去手机吧 )