TypeScript 是 JavaScript 的一个超集,它添加了静态类型检查和其他一些特性来帮助开发者编写更可靠、更易于维护的代码。在 TypeScript 中,Number 类型用于表示数值数据类型,包括整数和浮点数。TypeScript 的 Number 类型对应于 JavaScript 的原始数值类型。
Number 对象与基本 number 类型的区别
在 TypeScript(以及 JavaScript)中,number 类型和 Number 对象有明显的区别。理解这两者之间的差异对于正确使用数值类型非常重要。
基本 number 类型
- 原始值 :number是一种原始数据类型,它用于表示数值,包括整数和浮点数。它是直接存储的数值,而不是对象。
- 性能更高 :因为 number是原始值,所以它们的处理速度更快,占用的内存也更少。
- 不可变性 :作为原始值,number一旦创建就不能改变。每次对number进行操作都会产生一个新的数值。
- 用法简单 :当你只需要一个简单的数值时,通常会使用 number类型。
            
            
              typescript
              
              
            
          
          let age: number = 30;Number 对象
- 包装对象 :Number是一个构造函数,可以用来创建一个包装了原始数值的对象。它提供了额外的方法和属性来操作数值。
- 包含静态方法和属性 :Number对象包含了多个静态方法和属性,如Number.MAX_VALUE,Number.MIN_VALUE,Number.isNaN(), 等等。
- 可拥有属性 :由于是对象,Number实例可以拥有属性和方法,尽管这在实际开发中很少见。
- 性能较低 :相比于原始的 number类型,Number对象的操作可能会稍微慢一些,并且消耗更多的内存。
- 自动拆箱 :JavaScript 在需要的时候会自动将 Number对象转换为原始的number类型(称为"拆箱"),例如进行数学运算时。
            
            
              typescript
              
              
            
          
          let numObj = new Number(30);
console.log(numObj); // 输出: Number { 30 }注意事项
- 不要随意使用 new Number():在大多数情况下,没有必要使用new Number()来创建数值的包装对象。直接使用原始的number类型即可。使用new Number()可能会导致意外的行为,特别是在比较相等性时,因为两个不同的Number对象即使包含相同的数值也不会被认为是相等的。
            
            
              typescript
              
              
            
          
          let a = new Number(10);
let b = new Number(10);
console.log(a == b); // false, 因为它们是不同的对象
console.log(a === b); // false, 同上
console.log(a.valueOf() === b.valueOf()); // true, 比较的是内部的原始值- 静态方法的使用 :你可以直接通过 Number构造函数访问静态方法,而不需要创建Number的实例。例如:
            
            
              typescript
              
              
            
          
          let parsedInt = Number.parseInt("123"); // 使用静态方法 parseInt总之,在日常编程中,你应该优先选择使用基本的 number 类型,除非你有特定的理由需要使用 Number 对象。
Number 对象属性
Number 对象在 TypeScript 和 JavaScript 中提供了一些有用的静态属性,这些属性可以直接通过 Number 构造函数访问,而不需要创建 Number 的实例。以下是 Number 对象的一些常用属性:
静态属性
- 
Number.EPSILON: 表示1与大于1的最小浮点数之间的差异,用于比较浮点数以确定它们是否足够接近。typescriptconsole.log(Number.EPSILON); // 输出: 2.220446049250313e-16
- 
Number.MAX_SAFE_INTEGER: 可以安全使用的最大整数值(2^53 - 1)。typescriptconsole.log(Number.MAX_SAFE_INTEGER); // 输出: 9007199254740991
- 
Number.MIN_SAFE_INTEGER: 可以安全使用的最小整数值(-(2^53 - 1))。typescriptconsole.log(Number.MIN_SAFE_INTEGER); // 输出: -9007199254740991
- 
Number.MAX_VALUE: 能够表示的最大正数。typescriptconsole.log(Number.MAX_VALUE); // 输出: 1.7976931348623157e+308
- 
Number.MIN_VALUE: 能够表示的最接近零的正数(非零)。typescriptconsole.log(Number.MIN_VALUE); // 输出: 5e-324
- 
Number.NaN: 表示"不是数字"的特殊值。typescriptconsole.log(Number.NaN); // 输出: NaN
- 
Number.NEGATIVE_INFINITY: 表示负无穷大。typescriptconsole.log(Number.NEGATIVE_INFINITY); // 输出: -Infinity
- 
Number.POSITIVE_INFINITY: 表示正无穷大。typescriptconsole.log(Number.POSITIVE_INFINITY); // 输出: Infinity
使用注意事项
当使用 Number 对象的静态属性时,直接通过 Number 访问即可,不需要也不应该使用 new Number() 来创建对象实例来访问这些属性。例如:
            
            
              typescript
              
              
            
          
          // 正确用法
console.log(Number.MAX_VALUE);
// 错误用法,不应该这样做
let numObj = new Number(42);
console.log(numObj.MAX_VALUE); // 这不会工作,因为 MAX_VALUE 是静态属性以上列出的属性都是只读的,并且是静态的,意味着它们属于 Number 构造函数本身而不是它的实例。因此,当你需要使用这些常量时,总是直接从 Number 访问它们。
Number 对象方法
Number 对象在 TypeScript 和 JavaScript 中提供了许多静态方法和实例方法,用于数值的解析、格式化以及数值属性的检查等操作。这些方法可以帮助开发者更方便地处理数值类型的数据。以下是 Number 对象的一些常用方法:
静态方法
- 
Number.parseFloat(string): 将一个字符串解析为浮点数。typescriptconsole.log(Number.parseFloat("123.45")); // 输出: 123.45
- 
Number.parseInt(string, radix): 将一个字符串解析为整数。radix参数是可选的,指定了解析时所用的进制(例如,10 表示十进制)。typescriptconsole.log(Number.parseInt("101", 2)); // 输出: 5 (二进制)
- 
Number.isNaN(value): 检查给定值是否为NaN。它比全局的isNaN()函数更为严格,因为后者会尝试将非数字参数转换为数字再进行判断。typescriptconsole.log(Number.isNaN(NaN)); // true console.log(Number.isNaN(123)); // false
- 
Number.isFinite(value): 检查给定值是否为有限数值(既不是Infinity也不是-Infinity或NaN)。typescriptconsole.log(Number.isFinite(100)); // true console.log(Number.isFinite(Infinity)); // false
- 
Number.isInteger(value): 检查给定值是否为整数。typescriptconsole.log(Number.isInteger(100)); // true console.log(Number.isInteger(100.1)); // false
- 
Number.isSafeInteger(value): 检查给定值是否为安全整数(即,在Number.MIN_SAFE_INTEGER和Number.MAX_SAFE_INTEGER之间的整数)。typescriptconsole.log(Number.isSafeInteger(9007199254740991)); // true console.log(Number.isSafeInteger(9007199254740992)); // false
实例方法
对于通过 new Number(value) 创建的 Number 对象,或者直接使用原始数值(由于自动装箱机制),你可以调用以下方法:
- 
.toFixed(fractionDigits): 返回指定小数位数的字符串表示形式。typescriptlet num = 123.456; console.log(num.toFixed(2)); // "123.46"
- 
.toExponential(fractionDigits): 返回以指数记法表示的字符串。typescriptlet num = 123; console.log(num.toExponential(2)); // "1.23e+2"
- 
.toPrecision(precision): 返回指定精度的有效数字表示的字符串。typescriptlet num = 123.456; console.log(num.toPrecision(4)); // "123.5"
- 
.toString(radix): 返回数值的字符串表示,radix参数是可选的,指定了转换时使用的进制。typescriptlet num = 255; console.log(num.toString(16)); // "ff" (十六进制)
- 
.toLocaleString(locales, options): 根据本地化的格式返回数值的字符串表示。locales参数可以指定语言环境,options可以指定格式选项。typescriptlet num = 123456.789; console.log(num.toLocaleString('en-US')); // "123,456.789"
请注意,虽然你可以创建 Number 对象来访问这些方法,但在大多数情况下,直接在原始数值上调用这些方法就足够了。JavaScript 的自动装箱机制会临时将原始数值包装成对象,以便能够调用这些方法。因此,通常没有必要显式地使用 new Number() 构造函数。
Number 对象的使用建议
在 TypeScript(以及 JavaScript)中使用 Number 对象时,有几点建议可以帮助你编写更有效和更可靠的代码:
1. 避免不必要的 Number 对象实例化
- 
优先使用原始的 number类型 :除非有特殊需求,否则应该避免使用new Number()创建Number对象。原始数值类型性能更高,且更容易理解。typescript// 不推荐 let numObj = new Number(42); // 推荐 let num = 42;
2. 使用静态方法进行数值处理
- 
利用 Number的静态方法 :Number提供了多个静态方法来解析字符串、检查数值特性等。直接调用这些静态方法即可,无需创建Number实例。typescriptconsole.log(Number.parseInt("10")); // 使用静态方法 parseInt console.log(Number.isNaN(NaN)); // 使用静态方法 isNaN
3. 比较相等性时要小心
- 
注意相等性比较 :两个不同的 Number对象即使包含相同的数值也不会被认为是相等的。因此,在比较数值时,应确保它们都是原始类型的number。typescriptlet a = new Number(10); let b = new Number(10); console.log(a == b); // false, 因为它们是不同的对象 console.log(a.valueOf() === b.valueOf()); // true, 比较的是内部的原始值
4. 使用适当的数值检查方法
- 
选择合适的数值检查方法 :根据你的需要选择 Number.isNaN,Number.isFinite,Number.isInteger, 或Number.isSafeInteger等方法来进行精确的数值属性检查。typescriptconsole.log(Number.isInteger(100)); // true console.log(Number.isSafeInteger(9007199254740991)); // true
5. 格式化输出
- 
使用格式化方法 :当需要格式化数值输出时,可以使用 .toFixed(),.toExponential(),.toPrecision(), 和.toLocaleString()等方法。typescriptlet price = 123.456; console.log(price.toFixed(2)); // "123.46" console.log(price.toLocaleString('en-US', { style: 'currency', currency: 'USD' })); // "$123.46"
6. 处理浮点数精度问题
- 
意识到浮点数运算的精度问题 :JavaScript 中的浮点数运算可能会导致精度丢失的问题。如果需要高精度计算,考虑使用第三方库如 decimal.js。typescriptconsole.log(0.1 + 0.2); // 0.30000000000000004
7. 使用 Number.EPSILON 进行浮点数比较
- 
浮点数比较 :对于浮点数的比较,可以使用 Number.EPSILON来确定两个数是否足够接近,以考虑到浮点数的精度限制。typescriptfunction areCloseEnough(a, b) { return Math.abs(a - b) < Number.EPSILON; } console.log(areCloseEnough(0.1 + 0.2, 0.3)); // true
总结
总的来说,尽量使用原始的 number 类型,并充分利用 Number 构造函数提供的静态方法。只有当你确实需要一个 Number 对象提供的特定功能时,才应该创建 Number 实例。通过遵循这些建议,你可以写出更加高效和不易出错的代码。