ECMAScript 2016 中的 Symbol 详解与实践应用

前言

Symbol 是 ECMAScript 2015 引入的新类型,用于表示独一无二的值。在 ECMAScript 2016 中,Symbol 又进行了一些扩展和改进。本文将详细介绍 Symbol 的概念、用法和实践应用,希望对前端开发者有所帮助。

Symbol 的概念

Symbol 是一种新的原始数据类型,表示独一无二的值。它的概念类似于 Java 中的枚举类型,但更加灵活和强大。

Symbol 的定义方式如下:

--- --- - ---------

其中,let 是 ES6 中新增的块级作用域声明关键字,Symbol() 是 Symbol 的构造函数,用于创建一个新的 Symbol 值。每个 Symbol 值都是唯一的,即使创建时传入的参数相同。

Symbol 支持传入一个字符串作为参数,用于描述该 Symbol 的名称。这个名称只是一个描述符,不会影响 Symbol 的唯一性。例如:

--- ---- - --------------
--- ---- - --------------
---------------- --- ------ -- -----

上述代码中,sym1sym2 都是 Symbol 类型的值,但它们是不同的值,因为它们的名称不同。

Symbol 的另一个特点是不可枚举。这意味着它们不会出现在 for...in 循环中,也不会被 Object.keys() 和 JSON.stringify() 等方法包含。

Symbol 的用法

Symbol 主要用于两个方面:作为对象属性的键和作为私有成员变量。下面分别介绍这两个用法。

1. 作为对象属性的键

在 ES6 之前,我们通常使用字符串作为对象属性的键。但是,字符串作为键有一个缺点,就是容易重复。如果两个对象都有相同的属性名,那么它们就会相互覆盖,导致数据错误。

Symbol 的出现解决了这个问题。由于每个 Symbol 都是唯一的,所以可以用它作为对象属性的键,避免属性名冲突。例如:

--- --- - -
  ---------------- ---- -------
  ---------------- ---- ------
--
----------------- -- ------------- ---- ------- ------------ ---- -------

上述代码中,obj 是一个对象,它有两个属性,分别用 Symbol 类型的值作为键。这两个属性都是不可枚举的,因此无法通过 for...in 循环或 Object.keys() 方法访问到。

2. 作为私有成员变量

在传统的面向对象编程中,我们通常将对象的私有成员变量定义为对象的属性,并使用下划线开头来表示它们是私有的。但是,这种做法并不严格,因为外部仍然可以通过对象的属性访问到私有成员变量。

Symbol 的出现可以解决这个问题。我们可以将私有成员变量定义为对象的 Symbol 属性,这样外部就无法访问到它们。例如:

--- --- - -
  ------------------------ -------- -----
--
---------------------------------------- -- ---------

上述代码中,obj 是一个对象,它有一个名为 Symbol('privateData') 的属性,该属性存储了私有数据。由于该属性是不可枚举的,因此外部无法访问到它。只有对象内部的方法才能访问到这个私有数据。

Symbol 的实践应用

除了上述两个用法之外,Symbol 还有一些实践应用。下面分别介绍这些应用。

1. Symbol.iterator

ES6 引入了一种新的遍历器接口,可以用于遍历数据结构中的元素。这个接口定义在 Symbol.iterator 属性中,每个数据结构都可以实现这个接口,从而支持遍历。例如:

--- --- - --- -- ---
--- ---- - -----------------------
------------------------- -- ------- -- ----- ------
------------------------- -- ------- -- ----- ------
------------------------- -- ------- -- ----- ------
------------------------- -- ------- ---------- ----- -----

上述代码中,arr 是一个数组,它实现了 Symbol.iterator 接口,从而支持遍历。通过调用 arrSymbol.iterator 方法,可以获取到一个遍历器对象 iter,然后使用 iter.next() 方法依次遍历数组中的元素。

2. Symbol.for 和 Symbol.keyFor

Symbol.for 方法可以用于创建一个全局的 Symbol 值,该值可以被多个窗口或框架共享。例如:

--- ---- - ------------------
--- ---- - ------------------
---------------- --- ------ -- ----

上述代码中,sym1sym2 都是全局的 Symbol 值,它们的名称相同,因此它们是相等的。

Symbol.keyFor 方法可以用于获取一个全局 Symbol 值的名称。例如:

--- --- - ------------------
-------------------------------- -- -----

上述代码中,Symbol.keyFor(sym) 方法返回的是全局 Symbol 值 sym 的名称。

总结

Symbol 是 ECMAScript 2015 引入的新类型,用于表示独一无二的值。它可以作为对象属性的键和私有成员变量,还可以用于实现遍历器接口和创建全局 Symbol 值。Symbol 的出现,解决了对象属性名冲突和私有成员变量访问问题,是一种非常实用的新特性。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65ceb721add4f0e0ff8005d1