parseInt()和Number()有什么区别?

Mar*_*ark 313 javascript performance

如何parseInt()以及Number()将字符串转换为数字时不同的表现?

CMS*_*CMS 433

好吧,它们在语义上是不同的,被Number称为函数构造函数执行类型转换parseInt执行解析,例如:

// parsing:
parseInt("20px");       // 20
parseInt("10100", 2);   // 20
parseInt("2e1");        // 2

// type conversion
Number("20px");       // NaN
Number("2e1");        // 20, exponential notation
Run Code Online (Sandbox Code Playgroud)

请记住,如果parseInt检测到字符串上的前导零,它将解析八进制数中的数字,这在标准的新版本ECMAScript 5上已经改变,但是它需要很长时间才能进入浏览器实现(它是与ECMAScript 3)不兼容,parseInt也会忽略与当前使用的基数的任何数字不对应的尾随字符.

Number构造函数不检测八进制:

Number("010");         // 10
parseInt("010");       // 8, implicit octal
parseInt("010", 10);   // 10, decimal radix used
Run Code Online (Sandbox Code Playgroud)

但它可以用十六进制表示法处理数字,就像parseInt:

Number("0xF");   // 15
parseInt("0xF"); //15
Run Code Online (Sandbox Code Playgroud)

另外,一个广泛使用的构造来执行数值类型转换,是一元+运算符(第72页),它相当于使用Number构造函数作为函数:

+"2e1";   // 20
+"0xF";   // 15
+"010";   // 10
Run Code Online (Sandbox Code Playgroud)

  • 这次真是万分感谢。这是我第一次看到 NaN。有些人知道 NaN 是用函数 isNaN ( value ) 测试的,这可能会有所帮助。例如,仅使用“if ( value == NaN )”是行不通的。 (2认同)
  • `Number()` 处理八进制很像十六进制和二进制:`Number('0o10') == 8` (2认同)
  • `parseInt("010")` 在 Chrome 中返回 `10` (2认同)

let*_*nje 21

typeof parseInt("123") => number
typeof Number("123") => number
typeof new Number("123") => object (Number primitive wrapper object)
Run Code Online (Sandbox Code Playgroud)

前两个将为您提供更好的性能,因为它返回原语而不是对象.

  • `new Number()`与`Number()`不同.`typeof Number("123")=> number` (19认同)
  • @Kragen,如果你解释为什么你不应该使用"新号码",而不是只输入"从不"5次,对社区来说会更有益... (14认同)
  • 还有`new Number("1")!= new Number("1")`.**绝对不要使用"新号码"**.绝不永远不会永远.另一方面,`数字("1")`是完全合理的. (7认同)
  • @ken 很老的评论,但对于未来的访问者,我想这正是他们提到的原因。我解析两个数字`let x = new Number("2"); let y = new Number("2");` 然后不管什么原因做一个相等性检查,`if (x == y) { doSomething(); }` 逻辑上应该调用`doSomething`。但它不会。此外,如果您只解析一个数字 `let x = new Number("2");` 那么 `x === 2` 将是错误的。这就是为什么你不应该使用 `new Number` 的一个明确原因 (3认同)
  • @TomC 您看到的是编辑评论的结果(这就是评论后面的铅笔图标所表示的);以前是零解释,只是强烈的告诫。 (2认同)

Sau*_*ius 15

如果您正在寻找性能,那么可能是最好的结果,您可以通过按位右移"10">>0.也乘以("10" * 1)或不乘(~~"10").所有这些都更快的NumberparseInt.他们甚至有"功能"返回0表示没有数字参数.这是性能测试.

  • 总是比"无用"优化更喜欢代码清晰度.对于大多数用例,更优选"parseInt"或"Number".如果您使用每秒数百万次转换编程N64仿真器,您可能会考虑这些技巧. (13认同)
  • 请注意,这不能用于大整数——特别是不适合有符号 32 位整数的整数——因为在 JavaScript 中,按位运算符将其操作数视为 32 位序列,而不是十进制,十六进制或八进制数。因此 `(2**31).toString() >> 0` 将溢出到 `-2147483648`。您可以使用 `>>>` 而不是 `>>` 让 JavaScript 将操作数视为*无符号* 32 位整数,但任何大于 `2**32 - 1` 的数字也会溢出。 (3认同)
  • 今天我尝试了一下,发现`Number`按位领先,`*1`、`~~"10"`对我来说得分低得多。 (2认同)

zan*_*ngw 8

我发现的性能两个环节转换的几种方法中比较stringint.

parseInt(str,10)    
parseFloat(str)
str << 0
+str
str*1 
str-0
Number(str)
Run Code Online (Sandbox Code Playgroud)

http://jsben.ch/#/zGJHM

http://phrogz.net/js/string_to_number.html


kag*_*ick 8

除非您需要十六进制或八进制,否则最好远离 parseInt 并使用 Number 和 Math.round。两者都可以使用字符串。为什么要远离它?

parseInt(0.001, 10)
0

parseInt(-0.0000000001, 10)
-1

parseInt(0.0000000001, 10)
1

parseInt(4000000000000000000000, 10)
4
Run Code Online (Sandbox Code Playgroud)

它完全屠杀了非常大或非常小的数量。奇怪的是,如果这些输入是字符串,它就能正常工作。

parseInt("-0.0000000001", 10)
0

parseInt("0.0000000001", 10)
0

parseInt("4000000000000000000000", 10)
4e+21
Run Code Online (Sandbox Code Playgroud)

我不会冒着很难发现这个错误和人们提到的其他陷阱的风险,我会避免parseInt,除非你需要解析除基数 10 以外的东西NumberMath.round、 、Math.floor、 和.toFixed(0)都可以做同样的事情,parseInt而不需要这些类型的错误。

如果您确实想要或需要使用 parseInt 来实现它的某些其他特性,请不要使用它来将浮点数转换为整数。

  • 那是因为 `parseInt` _expects_ 字符串。任何非字符串首先被强制转换为字符串。由于 `4000000000000000000000` 不是一个安全整数,因此它的字符串表示形式是 `4e+21`,并且 `parseInt` 从左到右的解析在非数字 `e` 之前停止。将“parseInt”与数字参数一起使用或对数字进行舍入是一种误用。 (9认同)
  • 哇,这真的很有用!parseInt 中的错误确实很难找到。您的回答值得更多的点赞! (2认同)

小智 7

parseInt() -> 将数字解析为指定的 redix。

Number()-> 如果失败,则将指定的值转换为其等效的数值或 NaN。

因此,要将一些非数字值转换为数字,我们应该始终使用 Number() 函数。

例如。

Number("")//0
parseInt("")//NaN

Number("123")//123
parseInt("123")//123

Number("123ac") //NaN,as it is a non numeric string
parsInt("123ac") //123,it parse decimal number outof string

Number(true)//1
parseInt(true) //NaN
Run Code Online (Sandbox Code Playgroud)

parseInt()在进行 redix 转换时,函数有各种极端情况,因此我们应该避免使用 parseInt() 函数来进行强制转换。

现在,要检查天气提供的值是否为数字,我们应该使用本机isNaN()函数


Dio*_*ane 5

我总是使用parseInt,但要注意将导致它进入八进制模式的前导零.

  • 我认为为`parseInt(value,radix)提供一个基数总是一个好主意,这样你就不会有偶然的*八进制模式*转换等. (32认同)
  • 您还应该使用 linter,它会警告您在 `parseInt()` 中提供一个基数值。 (3认同)

Nae*_*ikh 5

一个微小的差别是他们转换什么undefined或者null

Number() Or Number(null) // returns 0
Run Code Online (Sandbox Code Playgroud)

parseInt() Or parseInt(null) // returns NaN
Run Code Online (Sandbox Code Playgroud)


Wil*_*een 5

摘要:

parseInt()

  • 将字符串作为第一个参数,将基数(整数作为数字系统的基数,例如十进制10或二进制2)作为第二个参数
  • 该函数返回一个整数,如果无法将第一个字符转换为数字,则将返回该整数NaN
  • 如果parseInt()函数遇到非数值,它将截断其余的输入字符串,仅解析该部分直到非数值。
  • 如果基数为undefined或0,则JS将假定以下内容:
    • 如果输入字符串以“ 0x”或“ 0X”开头,则基数为16(十六进制),则字符串的其余部分将解析为一个数字。
    • 如果输入值以0开头,则基数可以是8(八进制)或10(十进制)。选择哪个基数取决于JS引擎的实现。ES5指定应使用10。但是,并非所有浏览器都支持此功能,因此,如果您的数字可以以0开头,请始终指定基数。
    • 如果输入值以任何数字开头,则基数将为10

Number()

  • Number()构造可以任何参数输入转换成一个数字。如果Number()构造函数无法将输入转换为数字,NaN则将返回。
  • Number()构造还可以处理十六进制数,他们必须开始0x

例:

console.log(parseInt('0xF', 16));  // 15

// z is no number, it will only evaluate 0xF, therefore 15 is logged
console.log(parseInt('0xFz123', 16));

// because the radix is 10, A is considered a letter not a number (like in Hexadecimal)
// Therefore, A will be cut off the string and 10 is logged
console.log(parseInt('10A', 10));  // 10

// first character isnot a number, therefore parseInt will return NaN
console.log(parseInt('a1213', 10));


console.log('\n');


// start with 0X, therefore Number will interpret it as a hexadecimal value
console.log(Number('0x11'));

// Cannot be converted to a number, NaN will be returned, notice that
// the number constructor will not cut off a non number part like parseInt does
console.log(Number('123A'));

// scientific notation is allowed
console.log(Number('152e-1'));  // 15.21
Run Code Online (Sandbox Code Playgroud)