在 JavaScript 中,Number
和 number
的区别主要体现在类型和用途上。以下是详细的总结:
1. 类型区分
-
number
:是 JavaScript 的原始数据类型(primitive type),用于表示整数、浮点数以及特殊值(如NaN
、Infinity
)。let a = 42; // typeof a === "number"
-
Number
:是 JavaScript 的内置对象类型(对象包装器),用于创建数值对象。Number
是内置的全局对象,提供数值处理相关的属性和方法,例如Number.MAX_VALUE
表示最大数值,Number.MIN_VALUE
表示最小正数。let b = new Number(42); // typeof b === "object"
基本类型number
的值可以直接参与运算,而Number
对象封装了数值的扩展功能。
2. 存储与性能
number
:作为原始类型,直接存储在栈内存中,访问高效。Number
:作为对象,存储在堆内存中,栈中存储引用。频繁创建对象会影响性能。
3. 自动装箱(Auto-Boxing)
- 当对原始类型调用方法(如
a.toFixed(2)
)时,JavaScript 会临时将number
包装为Number
对象,调用方法后销毁。 - 这意味着原始类型可以“借用”对象的方法,但无需显式创建对象。
4. 比较与类型检查
-
宽松相等(
==
):原始类型与对象类型比较时,对象会被转换为原始值。console.log(5 == new Number(5)); // true
-
严格相等(
===
):类型不同直接返回false
。console.log(5 === new Number(5)); // false
-
typeof
结果:typeof 5; // "number" typeof new Number(5); // "object"
5. 使用场景
-
优先使用
number
:- 适用于所有数学运算、变量赋值等常规场景。
- 更高效且避免对象相关的副作用。
-
谨慎使用
Number
对象:-
需要为数值添加属性时(不推荐,易引发问题):
let numObj = new Number(10); numObj.customProp = 'hello'; // 可以添加属性
-
需要明确区分对象与原始类型的特殊场景。
-
6. 静态方法与实例方法
- 静态方法:通过
Number
构造函数调用,如Number.parseInt()
、Number.MAX_SAFE_INTEGER
。 - 实例方法:通过数值(原始或对象)调用,如
toFixed()
、toExponential()
。
7. TypeScript 中的类型注解
-
number
:注解原始类型。let a: number = 42; // 正确
-
Number
:注解对象类型(通常避免使用)。let b: Number = new Number(42); // 正确,但非推荐做法
8. 类型转换与常用方法
使用Number()
函数可将其他类型转换为number
,若转换失败则返回NaN
。parseInt()
和parseFloat()
专门用于字符串到数值的解析,支持进制转换和忽略非数字字符。例如,parseInt("10px")
返回10
。Number
对象的方法如toExponential()
(指数表示法)、toPrecision()
(指定精度)等,常用于数值格式化。
9. 特殊值与注意事项
NaN
(非数值)和Infinity
(无穷大)属于number
类型。需注意NaN !== NaN
,判断需用isNaN()
函数。浮点数运算可能存在精度问题(如0.1 + 0.2 !== 0.3
),可通过缩放为整数运算后还原。此外,避免直接比较浮点数,推荐使用误差范围判断。
10. 总结
特性 | number (原始类型) |
Number (对象类型) |
---|---|---|
存储方式 | 栈内存(直接存储值) | 堆内存(存储引用) |
性能 | 高效 | 较低(需内存分配) |
类型检查 (typeof ) |
"number" |
"object" |
添加属性 | 无效(自动装箱后销毁) | 有效(可作为对象属性) |
常见用途 | 常规数值操作 | 特殊需求(极少使用) |
建议:除非有明确需求,否则始终优先使用 number
。Number
对象可能导致意外的类型问题,且通常无必要。