ES6 JavaScript中Symbol的作用
从一开始接触es6,两三年了,JavaScript中有7种原始数据类型.
但是这个Symbol一直不知道有什么作用,不像es2020新出的bigint很好理解,就是大数运算用的,平时基本用不上,而且typescript没有支持这个语法编译到es5.
网上查了几篇文章,总结就是,Symbol的主要作用是作为对象的属性.
因为Symbol有两个特性
- 没有两个Symbol是相等的
- Symbol 数据值可以作为对象属性名(Symbol没出之前只能是字符串)
所以Symbol主要有以下两个使用场景
- 作为对象属性 当一个复杂对象中含有多个属性的时候,很容易将某个属性名覆盖掉,利用 Symbol 值作为属性名可以很好的避免这一现象。
const name = Symbol('name');
const obj = {
[name]: 'zhangsan',
}
- 模拟类的私有方法
ES6 中的类是没有 private 关键字来声明类的私有方法和私有变量的,但是我们可以利用 Symbol 的唯一性来模拟。
因为使用者在外部无法创建一个一样的speak,所以就无法在外部调用到这个方法
const speak = Symbol()
class Person {
[speak]() {
...
}
}
Symbol相关方法
let sym1 = Symbol('sym')
let sym2 = Symbol('sym')
console.log(sym1==sym2) ; // 输出 false
全局符号注册表
symbol.for()
可以在全局注册symbol
symbol.for() 会先检查全局运行时注册表,如果不存在则创建一个 symbol 实例并将其添加到全局符号注册表中,如果存在则直接返回该 symbol 实例。
let sym1 = Symbol.for('sym')
let sym2 = Symbol.for('sym')
console.log(sym1==sym2) ; // 输出 true
使用 Symbol.keyFor()
来查询全局符号注册表。通过接收参数为 symbol 类型,返回该 symbol 对应的字符串键,如果查询不到则返回 undefined
let s = Symbol.for('sym');
console.log(Symbol.keyFor(s)); // sym
console.log(Symbol.keyFor(s2)); // 报错 TypeError: s2 is not a symbol
常用内置 symbol
-
Symbol.hasInstance
方法,会被instanceof
运算符调用。构造器对象用来识别一个对象是否是其实例。 -
Symbol.isConcatSpreadable
布尔值,表示当在一个对象上调用Array.prototype.concat
时,这个对象的数组元素是否可展开。 -
Symbol.iterator
方法,被for-of
语句调用。返回对象的默认迭代器。 -
Symbol.match
方法,被String.prototype.match
调用。正则表达式用来匹配字符串。 -
Symbol.replace
方法,被String.prototype.replace
调用。正则表达式用来替换字符串中匹配的子串。 -
Symbol.search
方法,被String.prototype.search
调用。正则表达式返回被匹配部分在字符串中的索引。 -
Symbol.species
函数值,为一个构造函数。用来创建派生对象。 -
Symbol.split
方法,被String.prototype.split
调用。正则表达式来用分割字符串。 -
Symbol.toPrimitive
方法,被ToPrimitive
抽象操作调用。把对象转换为相应的原始值。 -
Symbol.toStringTag
方法,被内置方法Object.prototype.toString
调用。返回创建对象时默认的字符串描述。 -
Symbol.unscopables
对象,它自己拥有的属性会被with
作用域排除在外。
网友评论