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ː/nounprimit: 原始原始值A number can be a primitive value.
exponential notation/ˌekspəˈnenʃl noʊˈteɪʃn/nounex-: 出 + pon: 放置 + -ent + -ial指数表示法written using exponential notation
radix/ˈreɪdɪks/noun-基数an optional radix argument
decimal point/ˈdesɪml pɔɪnt/noundecim: 十 + -al小数点number of characters behind the decimal point
specify/ˈspesɪfaɪ/verbspec: 看 + -ify指定If you don’t specify it…
perfect/ˈpɜːfɪkt/adjper-: 完全 + fect: 做完美的perfect for working with money
internal/ɪnˈtɜːrnl/adjinter: 在内 + -nal内部的used internally in JavaScript
convert/kənˈvɜːt/verbcon-: 共同 + 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/nounmodul: 模块 + -ar + -ize + -ation模块化purpose is modularization of globals
finite/ˈfaɪnaɪt/adjfin: 结束 + -ite有限的a finite number
safe integer/seɪf ˈɪntɪdʒər/nounsafe: 安全, integer: 整数安全整数a safe integer
represent/ˌreprɪˈzent/verbre-: 再 + present: 呈现表示represented as a double precision number
precision/prɪˈsɪʒn/nounpre-: 前 + cis: 切 + -ion精度double precision number

更多推荐