重温 ES6 Symbol
本文于829天之前发表,文中内容可能已经过时。
创建了一个 “重学TypeScript” 的微信群,想加群的小伙伴,加我微信 “semlinker”,备注 “1” 。阿里、京东、腾讯的大佬都在群里等你哟。
Symbol 是 ES6 引入的一种新的原始数据类型,表示独一无二的值。
Symbol 特性
1.Symbol 通过工厂函数创建,不能以 new 的方式创建,所以使用 instanceof 运算符返回的结果为 false
1 | var sym = Symbol(); |
2.Symbol 使用 typeof 运算符返回 “symbol”
1 | var sym = Symbol('foo'); |
3.Symbol 工厂函数能支持一个可选的参数,用于描述当前的 symbol
1 | var sym2 = Symbol('foo'); |
4.Symbol 是唯一的,Symbol("foo") == Symbol("foo")
返回 false
1 | Symbol('foo') === Symbol('foo'); // false |
5.Symbol 与数值或字符串进行运算时,会抛出异常
1 | sym | 0 // TypeError |
6.Symbol 工厂函数返回的 symbol,可作为对象的属性名,可以避免属性冲突,在 for...in
迭代中不可枚举
1 | var obj = {}; |
7.Symbol 工厂函数返回的值,可作为对象属性名,当使用 JSON.stringify()
进行序列化时,该属性会被忽略
1 | JSON.stringify({[Symbol("foo")]: "foo"}); // '{}' |
8.Symbol 是唯一的,但可以使用 Symbol.for() 共享同一个 Symbol 值
1 | var mySymbol1 = Symbol.for('some key'); |
Symbol 实战
对象字面量私有属性和方法
1 | const myPrivateMethod = Symbol("myPrivateMethod"); |
除了在创建对象字面量时可以使用 Symbol 外,在定义类的私有属性和方法时也可以使用。
类的私有属性和方法
1 | const myPrivateMethod = Symbol("myPrivateMethod"); |
在 ES6 中,引入了一些全局的 Symbols,比如:Symbol.match,Symbol.replace,Symbol.search,Symbol.iterator 和 Symbol.split。这里我们简单介绍一下 Symbol.search 和 Symbol.iterator。
Symbol.iterator
1 | class Skill { |
Symbol.search
先来简单看个示例:
1 | 'angular'.search('ng') // 4 |
该示例的执行流程:
- 解析
'angular'.search('ng')
- 把 ‘angular’ 转换为字符串对象
new String('angular')
- 把 ‘ng’ 转换为正则对象
new Regexp('ng')
- 调用 ‘angular’ 字符串对象的
search
方法,该方法内部会自动调用ng
正则对象的Symbol.search
方法
具体可以参考以下伪代码:
1 | // pseudo code for String class |
此外利用 Symbol.search 我们还可以让 String.prototype.search()
方法调用我们自定义对象内部的 Symbol.search()
方法,从而实现自定义 search 逻辑:
1 | class Article { |
以上示例的执行流程:
- 解析
'Angular7'.search(article)
语句 - 把 ‘Angular7’ 转换为字符串对象
new String("Angular7")
- 由于 article 是对象,这里不需要进行转换
- 调用 ‘Angular7’ 字符串对象的
search
方法,该方法会自动调用article
对象内部的Symbol.search
方法,比如article[Symbol.search]('Angular7')
本文简单介绍了 ES6 Symbol 的一些特性,然后介绍了 Symbol 几个应用场景,若想进一步了解 Symbol,可以阅读一下冴羽大神写的ES6 系列之模拟实现 Symbol 类型这一篇文章。
参考资源
欢迎小伙伴们订阅全栈修仙之路,及时阅读 TypeScript、Node/Deno、Angular 技术栈最新文章。
