Number

重要的是,为了你的程序能够正常工作,它必须准确地处理数字。ES6增加了一些额外的属性和函数来辅助常见的数字操作。

两个在Number上新增的功能只是既存全局函数的引用:Number.parseInt(..)Number.parseFloat(..)

静态属性

ES6以静态属性的形式增加了一些有用的数字常数:

  • Number.EPSILON - 在任意两个数字之间的最小值:2^-52(关于为了应对浮点算数运算不精确的问题而将这个值用做容差的讲解,参见本系列的 类型与文法 的第二章)
  • Number.MAX_SAFE_INTEGER - 可以用一个JS数字值明确且“安全地”表示的最大整数:2^53 - 1
  • Number.MIN_SAFE_INTEGER - 可以用一个JS数字值明确且“安全地”表示的最小整数:-(2^53 - 1)(-2)^53 + 1.

注意: 关于“安全”整数的更多信息,参见本系列的 类型与文法 的第二章。

Number.isNaN(..) 静态函数

标准的全局isNaN(..)工具从一开始就坏掉了,因为不仅对实际的NaN值返回true,而且对不是数字的东西也返回true。其原因是它会将参数值强制转换为数字类型(这可能失败而导致一个NaN)。ES6增加了一个修复过的工具Number.isNaN(..),它可以正确工作:

  1. var a = NaN, b = "NaN", c = 42;
  2. isNaN( a ); // true
  3. isNaN( b ); // true —— 噢!
  4. isNaN( c ); // false
  5. Number.isNaN( a ); // true
  6. Number.isNaN( b ); // false —— 修好了!
  7. Number.isNaN( c ); // false

Number.isFinite(..) 静态函数

看到像isFinite(..)这样的函数名会诱使人们认为它单纯地意味着“不是无限”。但这不十分正确。这个新的ES6工具有更多的微妙之处。考虑如下代码:

  1. var a = NaN, b = Infinity, c = 42;
  2. Number.isFinite( a ); // false
  3. Number.isFinite( b ); // false
  4. Number.isFinite( c ); // true

标准的全局isFinite(..)会强制转换它收到的参数值,但是Number.isFinite(..)会省略强制转换的行为:

  1. var a = "42";
  2. isFinite( a ); // true
  3. Number.isFinite( a ); // false

你可能依然偏好强制转换,这时使用全局isFinite(..)是一个合法的选择。或者,并且可能是更明智的选择,你可以使用Number.isFinite(+x),它在将x传递前明确地将它强制转换为数字(参见本系列的 类型与文法 的第四章)。

整数相关的静态函数

JavaScript数字值总是浮点数(IEEE-754)。所以判定一个数字是否是“整数”的概念与检查它的类型无关,因为JS没有这样的区分。

取而代之的是,你需要检查这个值是否拥有非零的小数部分。这样做的最简单的方法通常是:

  1. x === Math.floor( x );

ES6增加了一个Number.isInteger(..)帮助工具,它可以潜在地判定这种性质,而且效率稍微高一些:

  1. Number.isInteger( 4 ); // true
  2. Number.isInteger( 4.2 ); // false

注意: 在JavaScript中,44.4.0,或4.0000之间没有区别。它们都将被认为是一个“整数”,因此都会从Number.isInteger(..)中给出true

另外,Number.isInteger(..)过滤了一些明显的非整数值,它们在x === Math.floor(x)中可能会被混淆:

  1. Number.isInteger( NaN ); // false
  2. Number.isInteger( Infinity ); // false

有时候处理“整数”是信息的重点,它可以简化特定的算法。由于为了仅留下整数而进行过滤,JS代码本身不会运行得更快,但是当仅有整数被使用时引擎可以采取几种优化技术(例如,asm.js)。

因为Number.isInteger(..)NanInfinity值的处理,定义一个isFloat(..)工具并不像!Number.isInteger(..)一样简单。你需要这么做:

  1. function isFloat(x) {
  2. return Number.isFinite( x ) && !Number.isInteger( x );
  3. }
  4. isFloat( 4.2 ); // true
  5. isFloat( 4 ); // false
  6. isFloat( NaN ); // false
  7. isFloat( Infinity ); // false

注意: 这看起来可能很奇怪,但是无穷即不应当被认为是整数也不应当被认为是浮点数。

ES6还定义了一个Number.isSafeInteger(..)工具,它检查一个值以确保它是一个整数并且在Number.MIN_SAFE_INTEGER-Number.MAX_SAFE_INTEGER的范围内(包含两端)。

  1. var x = Math.pow( 2, 53 ),
  2. y = Math.pow( -2, 53 );
  3. Number.isSafeInteger( x - 1 ); // true
  4. Number.isSafeInteger( y + 1 ); // true
  5. Number.isSafeInteger( x ); // false
  6. Number.isSafeInteger( y ); // false