《你不知道的JavaScript》之数字

86 阅读3分钟

数字的语法

JavaScript 中的数字常量一般用十进制表示。例如:

var a = 42;

var b = 42.3;

数字前面的 0 可以省略:

var a = 0.42;

var b = .42;

小数点后小数部分最后面的 0 也可以省略:

var a = 42.0
var b = 42.

对于 . 运算符需要给予特别注意,因为它是一个有效的数字字符,会被优先识别为数字常量的一部分,然后才是对象属性访问运算符。

// 无效语法:
42.toFixed( 3 ); // SyntaxError
// 下面的语法都有效:
(42).toFixed( 3 ); // "42.000"
0.42.toFixed( 3 ); // "0.420"
42..toFixed( 3 ); // "42.000"
42 .toFixed(3); // "42.000"(加了空格)

42.toFixed(3) 是无效的,因为 42. 会被优先识别成省略数字末尾0 的 42.0

我们还可以用指数形式来表示较大的数字,如:

var onethousand = 1E3; // 即 1 * 10^3

var onemilliononehundredthousand = 1.1E6; // 即 1.1 * 10^6

数字常量还可以用其他格式来表示,如二进制、八进制和十六进制。

当前的 JavaScript 版本都支持这些格式:

0xf3; // 243的十六进制

0Xf3; // 同上

0363; // 243的八进制

从 ES6 开始,严格模式(strict mode)不再支持 0363 八进制格式

ES6 支持以下新格式:

0o363; // 243的八进制
0O363; // 同上
0b11110011; // 243的二进制
0B11110011; // 同上

特殊的数字

NaN

如果数学运算的操作数不是数字类型(或者无法解析为常规的十进制或十六进制数字),

就无法返回一个有效的数字,这种情况下返回值为 NaN。

NaN 意指“不是一个数字”(not a number)

换句话说,“不是数字的数字”仍然是数字类型。

typeof NaN === "Number" // true

NaN 是一个特殊值,它和自身不相等,是唯一一个非自反

判断是不是NaN

  1. isNaN
    1.1 全局对象下的 isNaN

    isNaN(..) 有一个严重的缺陷,它的检查方式过于死板,就是“检查参数是否不是 NaN,也不是数字”。

    isNaN(NaN) // true
    isNaN("abc") // true
    isNaN("1") // false
    isNaN('') // false
    

    1.2 Number.isNaN

    该函数可直接判断是否是NaN,有且仅有 Number.isNaN(NaN) 才为true

  2. 利用自反性

    const a = "a" / 1
    a !== a // true
    

无穷数

熟悉传统编译型语言(如 C)的开发人员可能都遇到过编译错误(compiler error)或者运行时错误(runtime exception),例如“除以 0”:

var a = 1 / 0;

然而在 JavaScript 中上例的结果为 Infinity(即 Number.POSITIVE_INfiNITY)。

var a = 1 / 0; // Infinity
var b = -1 / 0; // -Infinity

计算结果一旦溢出为无穷数(infinity)就无法再得到有穷数。换句话说,就是你可以从有穷走向无穷,但无法从无穷回到有穷。

特殊的:

Infinity / Infinity // NaN(无穷除以无穷是NaN)
有穷正数 / Infinity // +0
有穷负数 / Infinity // -0

零值

JavaScript 有一个常规的 0(也叫作+0)和一个 -0。

  • 加法和减法运算不会得到负零(negative zero)。
  • 根据规范,对负零进行字符串化会返回 "0"
  • 如果反过来将其从字符串转换为数字,得到的结果是准确的
(-0).toString(); // "0"
-0 + ""; // "0"
String( a ); // "0"
JSON.stringify( a ); // "0"

+"-0"; // -0
Number( "-0" ); // -0
JSON.parse( "-0" ); // -0