symbol介绍
- symbol(符号) 是 ECMAscript 6 新增的简单数据类型,符号的实例是唯一的不可变的。它的主要作用是确保对象属性的唯一性,解决属性重复导致的问题。
基本使用
- 符号需要通过 Smybol() 函数初始化。因为 symbol 本身是原始类型,所以 typeof 返回的也是symbol 。
const sym = Symbol()
const obj = {
[sym]: 1
};
console.log(obj); // {Symbol(a): 1}
console.log(typeof sym); // symbol
- 调用 Symbol( ) 函数时,可以传递一个字符串入参对符号进行描述(注:该字符串入参对符号的定义是完全无关的
const sym1 = Symbol()
const sym2 = Symbol()
console.log(sym1, sym2, sym1 === sym2); // Symbol(), Symbol(), false
const a1 = Symbol('a')
const a2 = Symbol('a')
console.log(a1, a2, a1 === a2); // Symbol(a), Symbol(a), false
const obj={
[sym1]:'sym1',
[sym2]:'sym2',
[a1]:'a1',
[a2]:'a2',
}
console.log(obj); // {[Symbol()]: 'sym1',[Symbol()]: 'sym2',[Symbol(a)]: 'a1',[Symbol(a)]: 'a2'}
- Symbol() 函数是不能使用 new 关键字 ,如果使用 new 会报错误
const sym =new Symbol('new')
console.log(sym); // Symbol is not a constructor
全局 symbol 注册表
全局 symbol 注册表是指用一个字符串作为键,在全局 symbol 注册表创建并重用符号。通过 Symbol.for() 方法去创建符号(注:如果表中存在与该字符串对应的符号,会直接返回该符号),symbol.keyFor() 方法接收符号查询表中对应的字符串键。
const a1 = Symbol.for('a')
const a2 = Symbol.for('a')
console.log(a1, a2, a1 === a2); // Symbol(a) Symbol(a) true
console.log(Symbol.keyFor(a1)); // a
注意⚠️:即使采用相同的符号描述,全局 symbol 注册表中定义的符号与Symbol() 定义的符号是不同的。如果使用symbol.keyFor()查询的不是全局符号,则返回的是undefined
const a1 = Symbol('a')
const a2 = Symbol.for('a')
console.log(a1, a2, a1 === a2); // Symbol(a) Symbol(a) false
console.log(Symbol.keyFor(a1)); // undefined
symbol 内置的一些符号
ECMAscript 6 也引入了一批内置符号,我们可以直接访问,重写或模拟这些符号
Symbol.asyncIterator | 该方法返回一个对象 (默认的异步迭代器),可由 for - await - of 使用 |
Symbol.iterator | 该方法返回一个对象 (默认的迭代器), for of 循环时就会调用对象的 Symbol.iterator 函数 |
Symbol.isConcatSpreadable | 这个符号作为属性返回一个布尔值 , 默认为true( Array.prototype.concat() 方法就是通过该符号来判断是否将类数组打平其数组元素) |
Symbol.hasInstance | 该方法判断一个对象是不是属于这个构造函数的实例( instanceof 检测数据类型时的原理就是调用了该符号来实现的) |
Symbol.match | 该方法用正则表达式去匹配字符串(String.prototype.match 方法的原理就是调用了该符号来实现的) |
Symbol.replace | 该方法替换一个字符串中匹配的子串(String.prototype.replace 方法的原理就是调用了该符号来实现的) |
Symbol.search | 该方法返回字符串中匹配正则表达式的索引值(String.prototype.search 方法的原理就是调用了该符号来实现的) |
Symbol.split | 该方法在匹配正则表达式索引位置拆分字符串(String.prototype.split 方法的原理就是调用了该符号来实现的) |
Symbol.species | 该方法作为创建派生对象的构造函数 |
Symbol.toPrimitive | 该方法将对象转换为相应的原始值,由 toPrimitive 抽象操作使用 |
Symbol.toStringTag | 这个符号作为属性返回一个字符串,该字符串用于创建对象的默认字符串描述 ( String.prototype.toString 方法返回的结果就是调用了该符号来实现的) |