计算机在内部用位序列来表示数据。类型为这些位序列赋予了意义。
同时,类型限制了数据的取值范围。类型系统提供了一组基本类型或内置
类型,并为组合这些类型规定了一组规则。
基本类型
空类性
空类型是不能有任何值的类型,其可取值的集合是一个空集
合。我们任何时候都无法实例化这种类型的一个变量。我们使用空类
型来表示不可能,例如将其用作从不会返回的函数(抛出异常或无限
循环的函数)的返回类型。
单元类型
单元类型是只有一个可能值的类型。对于这种类型的变量,检查其值是没有意义的,它只能是那一个值。当函数的结果没有意义时,我们会使用单元类型。
布尔逻辑和短路
一些类型系统将布尔类型作为内置类型,提供了值 true 和 false。另一些系统则依赖数字来表示布尔值,它们将 0 视为 false,将其他意数字视为 true(即所有非假的就是真)。TypeScript 内置了一个 boolean 类型,其两个取值为 true 和 false。
大部分编译器和运行时会对布尔表达式进行所谓的“短路”优化。a AND b 形式的表达式会被翻译为 if a then b else false。这遵守 AND 的真值表:如果第一个操作数为 false,则无论第二个操作数是什么,整个表达式都是 false;如果第一个操作数为 true,那么当第二个操作数也为 true 时,整个表达式才为 true
对 a OR b 会进行类似的翻译,使其成为 if a then true else b。查看 OR 的真值表可知:如果第一个操作数为 true,则无论第二个操作数是什么,整个表达式都是 true;如果第一个操作数为 false,则只有第二个操作数为 true 时,整个表达式才为 true
之所以进行这种翻译,是因为如果计算第一个操作数已经能够知道整个表达式的结果,则完全不必计算第二个操作数,而这也是其名称“短路”的由来。守门人函数必须执行两个检查:一个开销相对小的检查,用于确保收到的评论不为空,以及一个开销可能很大的检查,涉及查询评论数据库。
浮点类型和圆整
在 TypeScript(和 JavaScript)中,使用 binary64 编码将数字表示为 64 位浮点数
- IEEE 标准定义了一些特殊值:
- NaN,代表非数字(not a number),用于表示无效操作(如除零)的结果。
- 正无穷和负无穷(Inf),当操作溢出时用作饱和值
- 尽管根据公式,0.10 变成了 0.100000000000000005551115123126,但这个数字将被向下圆整到 0.1。事实上,在 JavaScript 中进行比较时,认为 0.10 和 0.100000000000000005551115123126 相等。浮点数只能通过圆整和近似,才能使用相对少量的位数,表示很大范围中的小数。
精度值
JavaScript 提 供 了 Number.isSafeInteger(),可用来了解一个整数值是否能够在不被圆整的情况下表示出来。JavaScript 没 有 提 供 整 数 基 本 类 型 , 所 以 我 们 需 要 依 赖 于 Number.isSafeInteger()来防范圆整
比较浮点数
我们看到,由于存在圆整,比较浮点数的相等性通常不是一个好主意。有一种更好的方法来知道两个值是否近似相等:我们可以确保它们的差在给定阈值内。
这个阈值应该是多大?它应该是可能出现的最大圆整误差。这个值叫作 machine epsilon,随不同的编码而可能有所变化。JavaScript 将这个值作为 Number.EPSILON 提供。使用这个值时,我们可以实现两个数字的相等性比较,只需取出两个数字的差的绝对值,然后检查它是否小于 machine epsilon 即可。如果小于,则两个值在彼此的圆整误差之内,我们可以认为它们相等。
编码文本
字符串是另外一种常见的基本类型,用于表示文本。字符串由 0 个或更多个字符串组成,这就让它成为我们要讲解的第一个能够有无限个值的基本类型。
编码
我们需要了解字符编码,以更好地理解如何恰当地处理文本。Unicode 标 准 中 有 两 个 类 似 但 不 同 的 概 念 : 字 符 (character ) 和 书 写 位(grapheme)。字符是文本的计算机表示(警官表情符号、零宽连接字符串和女性符号),而书写位则是用户看到的符号(女警官)。渲染文本时,我们使用书写位,所以不应该拆分一个包含多字符的书写位。当编码文本时,我们使用字符。
字符与书写位:字形(glyph)是一个字符的特定表示。例如,“C”(加粗)和“C”(斜体)是字符“C”的两种不同的视觉呈现。书写位是一个不可分的单位,如果我们将其拆成不同部分,如女警官的示例那样,那么书写位将失去其意义。一个书写位可由多个字形来表示
使用数组和引用构建数据结构
固定大小数组依次存储给定类型的多个值,所以允许高效访问。引用类型则通过让组件引用其他组件,允许我们把一个数据结构拆分到多个位置。
我们不把变长数组视为基本类型,因为它们是使用固定大小数组和引用实现的。
固定大小数组
- 固定大小数组代表一个连续的内存区域,其中存储了相同类型的值。
- 相比链表,数组是一个常用的基本类型,原因在于效率:因为值是依次存储的,所以访问其中任何一个值都是速度很快的操作。
引用
- 引用类型保存对象的指针。引用类型的值,即变量的位,并不表示一个对象的内容,而是可以找到该对象的地址。一个对象的多个引用并不会
复制该对象的状态,所以通过其中一个引用修改该对象时,通过其他所有引用都可以看到做出的修改。
关联数组
JavaScript/TypeScript 数组是关联数组。
关联数组常常被实现为一个固定大小的列表数组。哈希函数接受任意类型的一个键,返回该固定数组的一个索引。在该数组的给定索引位置的列表中将添加或者检索键值对