【问题标题】:What is the difference between Number(...) and parseFloat(...)Number(...) 和 parseFloat(...) 有什么区别
【发布时间】:2012-08-12 21:13:18
【问题描述】:

What is the difference between parseInt(string) and Number(string) in JavaScript 之前已被询问过。

但答案基本上集中在radixparseInt"123htg" 之类的字符串转换为123 的能力。

我在这里要问的是,当您传递一个完全没有基数的实际数字字符串时,Number(...)parseFloat(...) 的返回值是否有很大差异。

【问题讨论】:

    标签: javascript string-conversion


    【解决方案1】:

    没有。两者都会导致调用内部ToNumber(string) 函数。

    来自ES5 section 15.7.1(作为函数调用的数字构造函数):

    Number 作为函数而不是构造函数调用时,它会执行类型转换...

    如果提供了 value,则返回由 ToNumber(value) 计算的 Number 值(不是 Number 对象),否则返回 +0

    来自ES5 section 15.1.2.3(parseFloat(字符串)):

    ... 如果trimmedStringtrimmedString 的任何前缀都不满足StrDecimalLiteral 的语法(见9.3.1) ...

    9.3.1 是标题为“ToNumber 应用于字符串类型”的部分,这就是第一个引号提到ToNumber(value) 时所指的内容。


    更新(见 cmets)

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

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

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

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

    【讨论】:

    • 你会得到一个 Number 对象,在非严格比较中,它的 valueOf 方法将被调用,但与非对象的严格比较会失败。与 Number 对象 IMO 混在一起是个坏主意(而且对于它的价值,Crockford 也不喜欢它们)
    【解决方案2】:

    请原谅我发布另一个答案,但我只是通过谷歌搜索来到这里,并没有找到我想要的所有详细信息。在 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 在所有情况下都返回一个数字,除了空格以外的非数字字符。

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

    【讨论】:

      【解决方案3】:

      正如@James Allardic 已经回答的那样,内部运作并没有那么不同。不过还是有区别的。使用parseFloat,以一个或多个数字字符后跟字母数字字符开头的(修剪)字符串可以转换为数字,Number 不会成功。如:

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

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

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

      【讨论】:

      • +1,这是真的,但在问题中定义的情况下,没有区别 - “当你传递一个实际的数字字符串时”。假设我已经正确理解了。
      • 另一个区别是 " """ 的结果,在这两种情况下 Number 将给出 0 但 parseFloat 给出 NaN
      • 我知道这件事。我什至说过,在 OP 中......这不是我要问的......
      【解决方案4】:

      只要您确定字符串中只有数字,就没有太大区别。如果有,Number 将返回 NaN
      使用Number 构造函数可能会遇到的另一个问题是同事可能会认为您忘记了new 关键字,并在稍后添加它,导致严格比较失败new Number(123) === 123 --> false 而@ 987654326@ --> 是的。

      一般来说,我更愿意保留 Number 构造函数的本来面目,只使用最短的语法将 cast 转换为 int/float:+numString,或使用 @ 987654329@.

      【讨论】:

      • 事实并非如此。 Number ("3 - 1") 将生成一个值为 3 的数字。
      【解决方案5】:

      当不使用new 为数值创建包装对象时,Number 被降级为简单地进行从字符串到数字的类型转换。

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

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

      【讨论】:

        猜你喜欢
        • 2011-02-15
        • 2011-01-23
        • 2018-06-03
        • 2012-09-23
        • 2016-03-24
        • 1970-01-01
        • 1970-01-01
        • 2011-06-01
        相关资源
        最近更新 更多