Symbol 是 ES6 新增的一种基本数据类型,用于表示唯一标识符。Symbol 类型是不可变的,不允许使用 new 操作符创建 Symbol 对象。本文将详细介绍 Symbol 类型的特性、用法以及相关示例。
Symbol 类型的基本特点
创建 Symbol
创建 Symbol 的方法是使用 Symbol()
函数,该函数可以接受一个可选的字符串参数,表示对 Symbol 的描述。
let mySymbol = Symbol(); let mySymbolWithDesc = Symbol('My Symbol');
需要注意的是,即使创建了相同的描述字符串,每次调用 Symbol()
函数都会返回一个全新的 Symbol 值,它们之间互不相等:
let sym1 = Symbol('foo'); let sym2 = Symbol('foo'); console.log(sym1 === sym2); // false
Symbol 作为属性名
由于每个 Symbol 值都是唯一的,因此它们可以用作对象属性名,这样就能避免属性名冲突的问题。
const MY_KEY = Symbol(); let obj = {}; obj[MY_KEY] = 123; console.log(obj[MY_KEY]); // 123
需要注意的是,在使用 for...in
和 Object.keys()
等方法遍历对象属性时,不会包含 Symbol 类型的属性。如果需要遍历 Symbol 属性,可以使用 Object.getOwnPropertySymbols()
方法。
预定义的 Symbol 值
ES6 预定义了一些 Symbol 值,它们在 JavaScript 内置对象中扮演着重要的角色。
Symbol.iterator
该 Symbol 值表示对象是否可被迭代。如果一个对象实现了
Symbol.iterator
方法,并且该方法返回一个迭代器对象,那么该对象就是可迭代的。例如,Array、Map、Set 等容器对象都实现了Symbol.iterator
方法,因此可以使用for...of
循环遍历它们。let arr = [1, 2, 3]; let iterator = arr[Symbol.iterator](); console.log(iterator.next()); // {value: 1, done: false} console.log(iterator.next()); // {value: 2, done: false} console.log(iterator.next()); // {value: 3, done: false} console.log(iterator.next()); // {value: undefined, done: true}
Symbol.hasInstance
该 Symbol 值表示对象是否为某个构造函数的实例。如果一个对象实现了
Symbol.hasInstance
方法,JavaScript 引擎会调用该方法来判断该对象是否为某个构造函数的实例。class MyClass { static [Symbol.hasInstance](obj) { return obj instanceof Array; } } console.log([] instanceof MyClass); // true
Symbol.species
该 Symbol 值表示根据给定的对象创建派生对象时应该使用的构造函数。例如,在 Array 的继承类中,如果需要创建一个新的 Array 实例,应该使用该继承类的构造函数而不是 Array 的构造函数。
-- -------------------- ---- ------- ----- ------- ------- ----- - ------ --- ------------------ - ------ ------ - - --- --- - --- ---------- -- --- --- ------- - ------------ ------------------- ---------- --------- -- ----- ------------------- ---------- ------- -- ----
Symbol.match
该 Symbol 值表示在字符串中检索是否存在某个匹配。如果一个对象实现了
Symbol.match
方法,JavaScript 引擎会调用该方法来进行字符串匹配操作。Symbol.replace
该 Symbol 值表示替换字符串中的某个匹配。如果一个对象实现了
Symbol.replace
方法,JavaScript 引擎会调用该方法来进行字符串替换操作。Symbol.search
该 Symbol 值表示搜索字符串中是否存在某个匹配。如果一个对象实现了
Symbol.search
方法,JavaScript 引擎会调用该方法来进行字符串搜索操作。Symbol.split
该 Symbol 值表示将字符串按照某个匹配进行分割。如果一个对象实现了
Symbol.split
方法,JavaScript 引擎会调用该方法来进行字符串分割操作。
在实际开发中的应用
用 Symbol 作为私有属性名
由于 Symbol 值的唯一性,我们可以用它来表示对象的私有属性。这种方法能够避免私有属性被篡改或者访问。
-- -------------------- ---- ------- ----- ----- - --------------- ----- ---- - -------------- ----- ------ - ----------------- ---- - ----------- - ----- ---------- - ---- - --------- - ------ ------------ - -------- - ------ ----------- - - --- ------ - --- ------------ ---- ------------------------------ -- ---- ----------------------------- -- -- -------------------------- -- --------- ------------------------- -- ---------
实现类似枚举类型的功能
在 ES6 之前,我们通常用 Object.freeze() 方法来实现枚举类型的功能。但是这种方法存在一个问题,就是属性名是字符串,容易被修改。而使用 Symbol 值则能够很好地解决这个问题。
-- -------------------- ---- ------- ----- ------- - - ------- ----------------- -------- ------------------ ---------- -------------------- --------- ------------------- ------- ----------------- --------- ------------------- ------- ---------------- -- ---------------------------- -- -------------- ----------------------------- -- --------------- ------------------------------- -- -----------------
实现迭代器对象
迭代器对象是一种可迭代的对象,可以使用 for...of
循环遍历它。Symbol 值的内置方法 Symbol.iterator
可以创建一个迭代器对象。可以使用该方法来实现自定义的迭代器对象。
-- -------------------- ---- ------- ----- ------- - ------------- - ---------- - --- - ---------------- - ------------------------- - -------------------- - --- ---- ---- -- ----------- - ----- ----- - - - --- --- - --- ---------- --------------- --------------- --------------- --- ---- ---- -- ---- - ------------------ -
总结
本文详细地介绍了 ES6 新增的 Symbol 类型,包括创建 Symbol、Symbol 作为属性名、预定义的 Symbol 值等。并且介绍了在实际开发中 Symbol 类型的应用,包括用 Symbol 作为私有属性名、实现类似枚举类型的功能以及实现迭代器对象等。相信在实际开发中,能够更加深入地理解和应用 Symbol 类型。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/645b06e4968c7c53b0d62de9