Number(...)与parseFloat(...)的区别是什么?

48

在JavaScript中,parseInt(string)和Number(string)有什么区别这个问题之前已经被询问过了。

但是答案基本上集中在radixparseInt能够接受像"123htg"这样的字符串并将其转换为123

我在这里问的是,当你传递一个实际的数字字符串而没有任何基数时,Number(...)parseFloat(...)的返回值是否有很大的区别。

5个回答

57

如@James Allardic已经回答的那样,内部工作方式并没有太大区别。不过还是有差别的。使用parseFloat,一个(修剪过的)以一个或多个数字字符开头,后跟字母数字字符的字符串可以转换为数字,而使用Number则不能成功转换。例如:

parseFloat('3.23abc'); //=> 3.23
Number('3.23abc'); //=> NaN

顺便提一下,在这两种转换中,输入字符串都会被修剪:

parseFloat('  3.23abc '); //=> 3.23
Number('   3.23 '); //=> 3.23

+1,这是正确的,但在问题定义的情况下,没有区别 - “当您将实际数字字符串传递给它时”。无论如何,我假设我已经正确理解了。 - James Allardice
6
另一个区别在于使用" """的结果,两种情况下Number函数都会给出0,但parseFloat会给出NaN - gray state is coming
我知道这个。我甚至在原始帖子中已经说过了...那不是我要问的... - Naftali
parseFloat('1.2.3'); // 1.2Number('1.2.3'); // NaN - Kip

31
不会。两者都将导致调用内部的ToNumber(string)函数。从ES5 section 15.7.1(作为函数调用的Number构造函数)中得知:当Number作为函数而不是构造函数被调用时,它执行类型转换...如果提供了value,则通过ToNumber(value)计算并返回一个Number值(而不是Number对象),否则返回+0。从ES5 section 15.1.2.3(parseFloat(string))中得知:...如果没有任何trimmedStringtrimmedString的前缀符合StrDecimalLiteral的语法(参见9.3.1)...。

9.3.1是题为“将ToNumber应用于字符串类型”的章节,当第一句引用ToNumber(value)时就是在指向该章节。


更新(请参见评论)

通过使用new运算符调用Number构造函数,您将获得Number对象的实例,而不是数值字面量。例如:

typeof new Number(10); //object
typeof Number(10); //number

这是在第15.7.2节(数字构造函数)中定义的:

Number作为new表达式的一部分被调用时,它是一个构造函数:它初始化新创建的对象。


你将会得到一个Number对象,在非严格比较中,它的valueOf方法将被调用,但是与非对象的严格比较将失败。在我看来,胡乱操作Number对象只是个坏主意(值得一提的是,Crockford也不喜欢它们)。 - Elias Van Ootegem

0

如果你确定字符串中只包含数字,那么使用Number的区别不大。但是如果有其他字符,Number会返回NaN
另一个问题是,使用Number构造函数时,同事可能会认为你忘记了new关键字,并在后面添加它,导致严格比较失败new Number(123) === 123 --> false,而Number(123) === 123 --> true。

一般来说,我更喜欢将Number构造函数保留为原样,只使用最短的语法来转换为整数/浮点数:+numString,或使用parse*


这并不是事实。Number("3 - 1")将产生一个值为3的数字。 - Josh Diehl

-1
请原谅我再次发表答案,但我是通过谷歌搜索到这里的,并没有找到我想要的所有细节。在Node.js中运行以下代码:
var vals = ["1", "1.1", "0", "1.1abc", "", " ", null];
for(var i = 0; i < vals.length; i++){
  var ifTest = false;
  if(vals[i])
  {
    ifTest = true;
  }
  console.log("val=" + vals[i] + ", Number()=" + Number(vals[i])+ ", parseFloat()=" + parseFloat(vals[i]) + ", if()=" + ifTest);
}

给出以下输出:

val=1, Number()=1, parseFloat()=1, if()=true
val=1.1, Number()=1.1, parseFloat()=1.1, if()=true
val=0, Number()=0, parseFloat()=0, if()=true
val=1.1abc, Number()=NaN, parseFloat()=1.1, if()=true
val=, Number()=0, parseFloat()=NaN, if()=false
val= , Number()=0, parseFloat()=NaN, if()=true
val=null, Number()=0, parseFloat()=NaN, if()=false

一些值得注意的要点:
  1. 在尝试转换为数字之前,如果使用 if(val) 进行保护,则 parseFloat() 将返回一个数字,除了空格的情况。
  2. 除了非数字字符(空格除外),Number 在所有情况下都会返回数字。

请随意添加任何我可能遗漏的测试用例。


-1

如果不使用 new 来创建一个数字值的包装对象,Number 只能从字符串转换成数字类型。

另一方面,正如你所提到的,parseFloat 可以从任何以数字、小数点或+/-开头的字符串中解析浮点数。

因此,如果您只使用包含纯数字值的字符串,则 Number(x)parseFloat(x) 将产生相同的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接