ECMAScript 2021 中的 Symbol 和 Symbol.iterator 的使用

· 约 6 分钟读完

在 ECMAScript 6 中引入了新的原生数据类型 Symbol,它的出现使得开发者可以创建独一无二的值,从而避免命名冲突和属性覆盖等问题。而在 ECMAScript 2021 中,Symbol 又有了更多的应用场景,同时还提供了一个新的内置的迭代器方法 Symbol.iterator,使得开发者可以更加便捷地使用迭代器。

Symbol

Symbol 是一种原始数据类型,用来表示一个独一无二的值。我们可以使用以下代码来创建一个 Symbol:

其中,Symbol 函数的参数是可选的,如果传入参数,就相当于一个 Symbol 实例的描述,但本质上它们是一样的。

1. Symbol 的应用场景

1.1. 属性名的保护

在对象中使用 Symbol 作为属性名,可以保证该属性名不被意外覆盖或访问到。如下面例子所示:

在这个例子中,我们将 x 设为对象 obj 的一个属性名,并将其值设为 'Hello'。而 y 属性则没有使用 Symbol,可以正常访问。

1.2. 私有属性和方法

使用 Symbol 来定义类的私有属性和方法,从而保证不会被外部访问到。如下所示:

在这个例子中,我们将 _name 设为私有属性的键名。并且在类的构造函数中初始化,并使用 [_name] 来定义私有方法。由此,在类外部将会不能访问到这些私有属性和方法。

1.3. 定义枚举

使用 Symbol 枚举,从而保证枚举值的独一无二性。如下所示:

在这个例子中,我们使用 Symbol 作为 Role 对象的属性名,从而定义了三个具有独一无二性的枚举值。

2. Symbol 属性的遍历

使用 Object.getOwnPropertySymbols 方法可以遍历出对象中所有使用 Symbol 作为属性名的属性。如下所示:

在这个例子中,使用 Object.getOwnPropertySymbols 方法遍历出 obj 对象中所有使用 Symbol 作为属性名的属性,并将它们存放在数组中。然后借助 for...of 循环输出属性名对应的值。

Symbol.iterator

Symbol.iterator 是 ECMAScript 6 新增的内置迭代器,它是一种通用的遍历方法,可以被所有的 Iterable 对象使用。使用 Symbol.iterator 可以方便地遍历出数据结构中的所有元素。

1. Iterator 接口实现

在一个对象上实现 Symbol.iterator 接口,需要满足以下两个条件:

  1. 对象需要具有一个 next 方法,返回一个满足 { value, done } 格式的对象。
  2. 对象上需要具有 Symbol.iterator 属性,该属性值为一个返回 Iterator 对象的函数。

以实现数组遍历为例:

在这个例子中,我们自己实现了 arr 数组上的 Symbol.iterator 方法。返回一个对象,该对象具有一个 next 方法。通过依次迭代数组中的元素,返回一个满足 { value, done } 的对象。

2. 内置迭代器

除了用户可以自己实现 Symbol.iterator 迭代器,许多内置容器对象也已经内置了该接口,方便我们进行遍历。

2.1. 数组的迭代器

数组已经内置了 Symbol.iterator 方法,可以使用 for...of 进行遍历。

2.2. 字符串的迭代器

字符串也内置了 Symbol.iterator 方法,可以使用 for...of 进行遍历。

2.3. Map 和 Set 迭代器

Map 和 Set 对象本身也内置了 Symbol.iterator 方法,可以使用 for...of 进行遍历。

3. 可迭代对象

具有 Symbol.iterator 属性的对象被称为可迭代对象,可以被 for...of 循环进行遍历。常见的可迭代对象包括数组、字符串、Set、Map。

结语

在 ECMAScript 2021 中,Symbol 和 Symbol.iterator 的应用更加广泛,对于开发者而言,掌握它们的应用和用法非常有必要。希望这篇文章对你有所帮助。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d7b9b1a941bf7134dd9ea4