JavaScript 中处理数字的各种方法涵盖基本数字方法(如 toString, toFixed)、全局转换函数(如 Number(), parseInt),以及重要的 Number 静态方法(如 Number.isInteger(), Number.isNaN())。文章通过丰富的代码示例、对比说明和 UML 图表,旨在帮助开发者牢固掌握数字处理的技巧与最佳实践,避免常见陷阱。

1. 数字处理:JavaScript 的基石

在 JavaScript 中,数字是一种基本数据类型,用于表示数值。处理数字是编程中的常见任务,无论是进行数学计算、格式化显示给用户,还是从用户输入或外部数据源中解析数字。JavaScript 提供了一系列强大的方法来帮助我们完成这些任务。这些方法主要分为三类:

  1. 基本数字方法 (Basic Number Methods):可以被任何数字(字面量、变量或表达式)调用。
  2. 全局转换方法 (Global Conversion Methods):用于将其他数据类型转换为数字。
  3. Number 静态方法 (Number Static Methods):只能通过 Number 对象本身调用。

理解这些方法的区别和适用场景,对于编写健壮和清晰的代码至关重要。

2. 基本数字方法 (Basic Number Methods)

基本数字方法可以直接在数字实例上调用。它们主要用于转换数字的表示形式(如转换为字符串、指数形式、固定小数位等)。

2.1 toString() 方法

toString() 方法返回一个表示指定数字的字符串。它可以接受一个可选的基数参数(radix),用于将数字转换为其他进制(如二进制、十六进制)。

// 示例代码
let x = 123;

// 将数字变量转换为字符串
x.toString();       // 返回 "123"
// 将数字字面量转换为字符串
(123).toString();   // 返回 "123"
// 将表达式结果转换为字符串
(100 + 23).toString(); // 返回 "123"

// 使用基数参数:转换为二进制
let text = x.toString(2); // 返回 "1111011"
// 转换为十六进制
x.toString(16); // 返回 "7b"

2.2 toExponential() 方法

toExponential() 方法返回一个以指数表示法表示的字符串,参数用于指定小数点后的位数。

// 示例代码
let x = 9.656;

x.toExponential(2); // 返回 "9.66e+0"
x.toExponential(4); // 返回 "9.6560e+0"
x.toExponential(6); // 返回 "9.656000e+0"
// 不指定参数,JavaScript 不会舍入数字,会尽可能多地显示小数位
x.toExponential();  // 返回 "9.656e+0"

2.3 toFixed() 方法

toFixed() 方法返回一个使用定点表示法表示的字符串,参数指定小数点后的位数。此方法非常适合处理货币金额

// 示例代码
let x = 9.656;

x.toFixed(0); // 返回 "10" (会四舍五入)
x.toFixed(2); // 返回 "9.66" (会四舍五入)
x.toFixed(4); // 返回 "9.6560"
x.toFixed(6); // 返回 "9.656000"

2.4 toPrecision() 方法

toPrecision() 方法返回一个指定长度的数字字符串。参数指定总位数(包括整数部分和小数部分)。

// 示例代码
let x = 9.656;

x.toPrecision();    // 返回 "9.656" (未指定长度,原样输出)
x.toPrecision(2);   // 返回 "9.7" (四舍五入到总长度为2)
x.toPrecision(4);   // 返回 "9.656"
x.toPrecision(6);   // 返回 "9.65600"

2.5 valueOf() 方法

valueOf() 方法返回一个数字的原始数值(primitive value)。在 JavaScript 中,数字既可以是原始类型(typeof === 'number'),也可以是对象(typeof === 'object',当你使用 new Number() 创建时)。valueOf() 方法主要在 JavaScript 内部用于将 Number 对象转换回原始值。在你的代码中通常没有理由直接使用它

// 示例代码
let x = 123;
x.valueOf();        // 返回 123 (数字)
(123).valueOf();    // 返回 123 (数字)
(100 + 23).valueOf(); // 返回 123 (数字)

所有 JavaScript 数据类型都拥有 valueOf()toString() 方法。

3. 全局转换方法 (Global Conversion Methods)

有 3 个全局 JavaScript 方法可用于将变量转换为数字。它们不属于任何对象,是全局可用的函数。

方法 描述
Number() 将其参数转换为数字返回。
parseFloat() 解析其参数并返回一个浮点数。
parseInt() 解析其参数并返回一个整数。

3.1 Number() 方法

Number() 方法可以转换各种 JavaScript 变量为数字。转换规则较为严格。

// 示例代码:转换布尔值、数字字符串
Number(true);        // 返回 1
Number(false);       // 返回 0
Number("10");        // 返回 10
Number("  10");      // 返回 10 (忽略前后空格)
Number("10  ");      // 返回 10
Number(" 10  ");     // 返回 10
Number("10.33");     // 返回 10.33
// 示例代码:转换失败的情况
Number("10,33");     // 返回 NaN (逗号无效)
Number("10 33");     // 返回 NaN (空格分隔的数字无效)
Number("John");      // 返回 NaN (纯文本无效)
// 如果无法转换,返回 NaN (Not a Number)。

Number() 用于日期
Number() 也可以将日期转换为数字,结果是自 1970 年 1 月 1 日(UTC)起的毫秒数。

// 示例代码
Number(new Date("1970-01-01")); // 返回 0 (纪元起点)
Number(new Date("1970-01-02")); // 返回 86400000 (24 * 60 * 60 * 1000)
Number(new Date("2017-09-30")); // 返回 1506729600000 (具体时间戳)

3.2 parseInt() 方法

parseInt() 解析一个字符串并返回一个整数。它会忽略前导空格,并且只返回字符串中的第一个数字

// 示例代码
parseInt("-10");        // 返回 -10
parseInt("-10.33");     // 返回 -10 (丢弃小数部分)
parseInt("10");         // 返回 10
parseInt("10.33");      // 返回 10
parseInt("10 20 30");   // 返回 10 (只解析第一个数字)
parseInt("10 years");   // 返回 10 (忽略后续非数字字符)
parseInt("years 10");   // 返回 NaN (第一个字符无法转换为数字)

3.3 parseFloat() 方法

parseFloat() 解析一个字符串并返回一个浮点数。同样,它会忽略前导空格,并且只返回字符串中的第一个数字

// 示例代码
parseFloat("10");         // 返回 10
parseFloat("10.33");      // 返回 10.33
parseFloat("10 20 30");   // 返回 10
parseFloat("10 years");   // 返回 10
parseFloat("years 10");   // 返回 NaN

4. Number 静态方法 (Number Static Methods)

这些方法属于 Number 对象本身,而不是数字实例。它们通常用于检查和验证数字,或者作为全局函数的模块化版本。你不能在变量上直接调用这些方法(例如 x.isInteger() 会报错),必须通过 Number 调用(例如 Number.isInteger(x))。

方法 描述
Number.isInteger() 如果参数是整数则返回 true
Number.isFinite() 如果参数是有限数字(非 InfinityNaN)则返回 true
Number.isNaN() 如果参数是 NaN 则返回 true (首选检查方法)
Number.isSafeInteger() 如果参数是安全整数则返回 true
Number.parseFloat() 同全局 parseFloat(),模块化目的
Number.parseInt() 同全局 parseInt(),模块化目的

为了更清晰地理解这些方法的关系和调用方式,可以参考以下 UML 类图:

creates
Same function for parseInt/parseFloat
«global object»
Number
+isInteger(arg)
+isFinite(arg)
+isNaN(arg)
+isSafeInteger(arg)
+parseInt(string)
+parseFloat(string)
NumberInstance
+toString(radix)
+toExponential(digits)
+toFixed(digits)
+toPrecision(precision)
+valueOf()
Global
+parseInt(string)
+parseFloat(string)
+Number(value)

此图描述了:

  • Number 是一个全局对象,它提供了静态方法(如 isInteger)和创建 NumberInstance 的能力。
  • NumberInstance 是数字实例,拥有基本方法(如 toString)。
  • Global 范围下的全局函数 parseInt/parseFloatNumber.parseInt/Number.parseFloat 功能相同。

4.1 Number.isInteger() 方法

判断参数是否为整数。

// 示例代码
Number.isInteger(10);    // 返回 true
Number.isInteger(10.5);  // 返回 false
Number.isInteger(null);  // 返回 false
Number.isInteger('10');  // 返回 false

4.2 Number.isFinite() 方法

判断参数是否是一个有限数字(即不是 Infinity-Infinity,也不是 NaN)。

// 示例代码
Number.isFinite(123);        // 返回 true
Number.isFinite(Infinity);   // 返回 false
Number.isFinite(-Infinity);  // 返回 false
Number.isFinite(NaN);        // 返回 false
Number.isFinite('123');      // 返回 false
// 与全局 isFinite() 的区别:全局的 isFinite() 会先尝试将参数转换为数字
isFinite('123'); // 返回 true
Number.isFinite('123'); // 返回 false (更严格)

4.3 Number.isNaN() 方法

判断参数是否是 NaN这是检查 NaN 的首选方法。你不能使用 ===== 来直接判断一个值是否等于 NaN,因为 NaN === NaN 返回 false

// 示例代码
Number.isNaN(123);       // 返回 false
Number.isNaN(NaN);       // 返回 true
Number.isNaN('NaN');     // 返回 false (字符串不是 NaN)
Number.isNaN(0 / 0);     // 返回 true (计算结果是 NaN)
// 与全局 isNaN() 的区别:全局的 isNaN() 会先尝试将参数转换为数字
isNaN('Hello'); // 返回 true
Number.isNaN('Hello'); // 返回 false (更严格)

4.4 Number.isSafeInteger() 方法

安全整数是指可以精确表示为双精度浮点数的整数。安全整数的范围在 -(2^53 - 1)+(2^53 - 1) 之间(即 -90071992547409919007199254740991)。超出此范围的整数在存储和计算时可能会失去精度。

// 示例代码
Number.isSafeInteger(10); // 返回 true
Number.isSafeInteger(12345678901234567890); // 返回 false
// 边界示例
Number.isSafeInteger(9007199254740991); // 返回 true
Number.isSafeInteger(9007199254740992); // 返回 false

4.5 Number.parseFloat()Number.parseInt() 方法

这两个方法与全局的 parseFloat()parseInt() 功能完全相同。它们被添加到 Number 对象的主要目的是模块化全局变量,使得代码(例如 ES6 模块)更容易在浏览器和非浏览器环境(如 Node.js)中共享,而不必依赖全局作用域。

// 示例代码:功能与全局方法一致
Number.parseFloat("10.33") // 返回 10.33
Number.parseInt("10.33")   // 返回 10

5. 单词、短语表

单词/短语 (Word/Phrase) 音标 (Phonetic) 词性 (Part of Speech) 词根/词缀 (Root/Affix) 释义 (Definition) 搭配/例子 (Collocation/Example)
method /ˈmeθəd/ noun - 方法 number methods, toString() method
primitive value /ˈprɪmɪtɪv ˈvæljuː/ noun primit: 原始 原始值 A number can be a primitive value.
exponential notation /ˌekspəˈnenʃl noʊˈteɪʃn/ noun ex-: 出 + pon: 放置 + -ent + -ial 指数表示法 written using exponential notation
radix /ˈreɪdɪks/ noun - 基数 an optional radix argument
decimal point /ˈdesɪml pɔɪnt/ noun decim: 十 + -al 小数点 number of characters behind the decimal point
specify /ˈspesɪfaɪ/ verb spec: 看 + -ify 指定 If you don’t specify it…
perfect /ˈpɜːfɪkt/ adj per-: 完全 + fect: 做 完美的 perfect for working with money
internal /ɪnˈtɜːrnl/ adj inter: 在内 + -nal 内部的 used internally in JavaScript
convert /kənˈvɜːt/ verb con-: 共同 + vert: 转 转换 convert variables to numbers
argument /ˈɑːrɡjumənt/ noun - 参数 converts from its argument
parse /pɑːrs/ verb - 解析 parses its argument
modularization /ˌmɒdʒələraɪˈzeɪʃn/ noun modul: 模块 + -ar + -ize + -ation 模块化 purpose is modularization of globals
finite /ˈfaɪnaɪt/ adj fin: 结束 + -ite 有限的 a finite number
safe integer /seɪf ˈɪntɪdʒər/ noun safe: 安全, integer: 整数 安全整数 a safe integer
represent /ˌreprɪˈzent/ verb re-: 再 + present: 呈现 表示 represented as a double precision number
precision /prɪˈsɪʒn/ noun pre-: 前 + cis: 切 + -ion 精度 double precision number

更多推荐