7_TypeScript Number --[深入浅出 TypeScript 测试]

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的最小浮点数之间的差异,用于比较浮点数以确定它们是否足够接近。

    typescript 复制代码
    console.log(Number.EPSILON); // 输出: 2.220446049250313e-16
  • Number.MAX_SAFE_INTEGER: 可以安全使用的最大整数值(2^53 - 1)。

    typescript 复制代码
    console.log(Number.MAX_SAFE_INTEGER); // 输出: 9007199254740991
  • Number.MIN_SAFE_INTEGER: 可以安全使用的最小整数值(-(2^53 - 1))。

    typescript 复制代码
    console.log(Number.MIN_SAFE_INTEGER); // 输出: -9007199254740991
  • Number.MAX_VALUE: 能够表示的最大正数。

    typescript 复制代码
    console.log(Number.MAX_VALUE); // 输出: 1.7976931348623157e+308
  • Number.MIN_VALUE: 能够表示的最接近零的正数(非零)。

    typescript 复制代码
    console.log(Number.MIN_VALUE); // 输出: 5e-324
  • Number.NaN: 表示"不是数字"的特殊值。

    typescript 复制代码
    console.log(Number.NaN); // 输出: NaN
  • Number.NEGATIVE_INFINITY: 表示负无穷大。

    typescript 复制代码
    console.log(Number.NEGATIVE_INFINITY); // 输出: -Infinity
  • Number.POSITIVE_INFINITY: 表示正无穷大。

    typescript 复制代码
    console.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): 将一个字符串解析为浮点数。

    typescript 复制代码
    console.log(Number.parseFloat("123.45")); // 输出: 123.45
  • Number.parseInt(string, radix) : 将一个字符串解析为整数。radix 参数是可选的,指定了解析时所用的进制(例如,10 表示十进制)。

    typescript 复制代码
    console.log(Number.parseInt("101", 2)); // 输出: 5 (二进制)
  • Number.isNaN(value) : 检查给定值是否为 NaN。它比全局的 isNaN() 函数更为严格,因为后者会尝试将非数字参数转换为数字再进行判断。

    typescript 复制代码
    console.log(Number.isNaN(NaN)); // true
    console.log(Number.isNaN(123)); // false
  • Number.isFinite(value) : 检查给定值是否为有限数值(既不是 Infinity 也不是 -InfinityNaN)。

    typescript 复制代码
    console.log(Number.isFinite(100)); // true
    console.log(Number.isFinite(Infinity)); // false
  • Number.isInteger(value): 检查给定值是否为整数。

    typescript 复制代码
    console.log(Number.isInteger(100)); // true
    console.log(Number.isInteger(100.1)); // false
  • Number.isSafeInteger(value) : 检查给定值是否为安全整数(即,在 Number.MIN_SAFE_INTEGERNumber.MAX_SAFE_INTEGER 之间的整数)。

    typescript 复制代码
    console.log(Number.isSafeInteger(9007199254740991)); // true
    console.log(Number.isSafeInteger(9007199254740992)); // false

实例方法

对于通过 new Number(value) 创建的 Number 对象,或者直接使用原始数值(由于自动装箱机制),你可以调用以下方法:

  • .toFixed(fractionDigits): 返回指定小数位数的字符串表示形式。

    typescript 复制代码
    let num = 123.456;
    console.log(num.toFixed(2)); // "123.46"
  • .toExponential(fractionDigits): 返回以指数记法表示的字符串。

    typescript 复制代码
    let num = 123;
    console.log(num.toExponential(2)); // "1.23e+2"
  • .toPrecision(precision): 返回指定精度的有效数字表示的字符串。

    typescript 复制代码
    let num = 123.456;
    console.log(num.toPrecision(4)); // "123.5"
  • .toString(radix) : 返回数值的字符串表示,radix 参数是可选的,指定了转换时使用的进制。

    typescript 复制代码
    let num = 255;
    console.log(num.toString(16)); // "ff" (十六进制)
  • .toLocaleString(locales, options) : 根据本地化的格式返回数值的字符串表示。locales 参数可以指定语言环境,options 可以指定格式选项。

    typescript 复制代码
    let 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 实例。

    typescript 复制代码
    console.log(Number.parseInt("10")); // 使用静态方法 parseInt
    console.log(Number.isNaN(NaN));     // 使用静态方法 isNaN

3. 比较相等性时要小心

  • 注意相等性比较 :两个不同的 Number 对象即使包含相同的数值也不会被认为是相等的。因此,在比较数值时,应确保它们都是原始类型的 number

    typescript 复制代码
    let 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 等方法来进行精确的数值属性检查。

    typescript 复制代码
    console.log(Number.isInteger(100)); // true
    console.log(Number.isSafeInteger(9007199254740991)); // true

5. 格式化输出

  • 使用格式化方法 :当需要格式化数值输出时,可以使用 .toFixed(), .toExponential(), .toPrecision(), 和 .toLocaleString() 等方法。

    typescript 复制代码
    let 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

    typescript 复制代码
    console.log(0.1 + 0.2); // 0.30000000000000004

7. 使用 Number.EPSILON 进行浮点数比较

  • 浮点数比较 :对于浮点数的比较,可以使用 Number.EPSILON 来确定两个数是否足够接近,以考虑到浮点数的精度限制。

    typescript 复制代码
    function areCloseEnough(a, b) {
        return Math.abs(a - b) < Number.EPSILON;
    }
    
    console.log(areCloseEnough(0.1 + 0.2, 0.3)); // true

总结

总的来说,尽量使用原始的 number 类型,并充分利用 Number 构造函数提供的静态方法。只有当你确实需要一个 Number 对象提供的特定功能时,才应该创建 Number 实例。通过遵循这些建议,你可以写出更加高效和不易出错的代码。

相关推荐
热爱编程的小曾9 分钟前
sqli-labs靶场 less 8
前端·数据库·less
gongzemin20 分钟前
React 和 Vue3 在事件传递的区别
前端·vue.js·react.js
Apifox33 分钟前
如何在 Apifox 中通过 Runner 运行包含云端数据库连接配置的测试场景
前端·后端·ci/cd
-代号952737 分钟前
【JavaScript】十四、轮播图
javascript·css·css3
树上有只程序猿1 小时前
后端思维之高并发处理方案
前端
庸俗今天不摸鱼2 小时前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
QTX187302 小时前
JavaScript 中的原型链与继承
开发语言·javascript·原型模式
黄毛火烧雪下2 小时前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox2 小时前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员
一张假钞2 小时前
Firefox默认在新标签页打开收藏栏链接
前端·firefox