数据类型

计算机程序是通过操作值来运行的,数据类型是值的一个属性,它能够描述在该值上允许执行的操作。在 ECMAScript 2015 规范中定义了如下七种数据类型:

  • Undefined

  • Null

  • Boolean

  • String

  • Symbol

  • Number

  • Object

其中,UndefinedNullBooleanStringSymbolNumber 类型是原始数据类型,Object 类型是非原始数据类型。原始数据类型是编程语言内置的基础数据类型,可用于构造复合类型。

Undefined

Undefined 类型只包含一个值,即 undefined。在变量未被初始化时,它的值为 undefined

Null

Null 类型也只包含一个值,即 null。我们通常使用 null 值来表示未初始化的对象。此外,null 值也常被用在 JSON 文件中,表示一个值不存在。

Boolean

Boolean 类型包含两个逻辑值,分别是 truefalse

String

String 类型表示文本字符串,它由 0 个或多个字符构成。

JavaScript 使用 UTF-16 编码来表示一个字符。UTF-16 编码以两个字节作为一个编码单元,每个字符使用一个编码单元或者两个编码单元来表示。在底层存储中,字符串是由零个或多个 16 位无符号整数构成的有序序列。例如,字符串 'ab' 的存储结构如图3-4所示。

image 2024 02 06 13 25 29 850
Figure 1. 图3-4 字符串’ab’的存储结构

在获取字符串长度时,返回的是字符串中包含的编码单元的数量。对于字符串 'ab' 而言,返回的长度是 2。因为字符 'a' 和字符 'b' 均由一个编码单元表示,总和为 2。前面介绍过,在 UTF-16 编码中,一个字符可能使用一个编码单元或者两个编码单元来表示。若字符串中包含需要使用两个编码单元表示的字符,那么获取字符串长度的结果可能不符合预期。例如下面的字符串:

'♡'.length; // 2

此例中,我们在获取字符 “心型” 的长度时得到的结果为 2,而期望的结果可能为 1。这是因为 “心型” 字符需要使用两个编码单元来表示,即 32 个二进制位。字符串 “心型” 的存储结构如图 3-5 所示。

image 2024 02 06 13 27 54 963
Figure 2. 图3-5 字符串’心型’的存储结构

此外,ECMAScript 2015 规定了字符串允许的最大长度为 253 - 1,该数值也是 JavaScript 所能安全表示的最大整数。

Number

Number 类型表示一个数字。JavaScript 不详细区分整数类型、浮点数类型以及带符号的数字类型等。JavaScript 使用双精度 64 位浮点数格式(IEEE 754)来表示数字,因此所有数字本质上都是浮点数。在该格式中,符号部分占用 1 位(bit),指数部分占用 11 位,小数部分占用 52 位,一共占用 64 位。具体结构如图3-6所示。

image 2024 02 06 13 29 57 929
Figure 3. 图3-6 IEEE 754双精度64位浮点数表示法

Symbol

Symbol 是 ECMAScript 2015 新引入的原始类型。Symbol 值有一个重要特征,那就是每一个 Symbol 值都是唯一的且不可改变的。Symbol 值的主要应用场景是作为对象的属性名。

Symbol 的设计初衷是用来实现对象的私有属性,但实际上 Symbol 并不能实现真正意义上的私有属性。JavaScript 还是提供了一些方法允许程序去访问 Symbol 属性。虽然 Symbol 无法实现绝对的私有属性,但是它确实有助于缓解属性命名冲突问题。

Symbol()

JavaScript 提供了一个全局的 “Symbol()” 函数来创建 Symbol 类型的值。我们可以将 “Symbol()” 函数想象成 GUID(全局唯一标识符)的生成器,每次调用 “Symbol()” 函数都会生成一个完全不同的 Symbol 值。示例如下:

const sym = Symbol();
const obj = { [sym]: 'some value' };
obj[sym]; // 'some value'

Well-Known Symbol

JavaScript 内置了一些所谓的 Well-Known Symbol 常量。这些 Symbol 常量用作对象属性名,它们的功能是定制对象的特定行为。在 ECMAScript 2015 规范中一共定义了 11 个 Well-Known Symbol 常量,如表3-1所示。

image 2024 02 06 13 35 04 432
Figure 4. 表3-1 Well-Known Symbol常量

Object

对象是属性的集合,每个对象属性都属于以下两种形式之一:

  • 数据属性。可以为 UndefinedNullBooleanStringNumberSymbolObject 类型的值。

  • 存取器属性。由一个或两个存取器方法构成,用于获取和设置 UndefinedNullBooleanStringNumberSymbolObject 类型的值。

对象属性使用键值来标识,键值只能为 字符串Symbol 值。所有字符串(也包括空字符串)和 Symbol 值都是合法的键值。