一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情。
ECMAScript 有 6 种简单数据类型(也称为原始类型):Undefined、Null、Boolean、Number、String 和 Symbol。Symbol(符号)是 ECMAScript 6 新增的。
symbol 是原始值,且符号实例是唯一、不可变的。symbol 用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。
所以常用的场景:创建唯一记号。
基本用法
- 初始化
let sym = Symbol();
// 支持传递参数
let bsym = Symbol('BBB');
使用Symbol()函数时,也支持传递一个字符串参数,用途是对符号的描述(description),将来可以通过这个字符串来调试代码。但是这个参数跟 symbol 没有任何关系。
- 只要创建就是一个唯一的记号
let asym = Symbol('nanlv')
let bsym = Symbol('nanlv')
console.log(asym==bsym) ; // 输出 false
- 创建即唯一:只要创建 Symbol()实例并将其用作对象的新属性,就可以保证它不会覆盖已有的对象属性。
- 不能与 new 一起使用
使用全局符号注册表
创建全局 symbol
当有部分功能可能需要共享或者重用时,那么可以用一个字符串作为键,在全局符号注册表中创建并重用 symbol。常用 symbol.for()
方法。
symbol.for() 会先检查全局运行时注册表,如果不存在则创建一个 symbol 实例并将其添加到全局符号注册表中,如果存在则直接返回该 symbol 实例。
let asym = Symbol.for('nanlv')
let bsym = Symbol.for('nanlv')
console.log(asym==bsym) ; // 输出 true
但是需要注意,如果仅使用 symbol() 初始化实例时不能和 Symbol.for() 的实例时不相等的。
let asym = Symbol('nanlv')
let bsym = Symbol.for('nanlv')
console.log(asym==bsym) ; // 输出 false
Symbol.for() 必须使用加上参数,即使用字符串键来创建。
查询全局 symbol
使用 Symbol.keyFor()来查询全局符号注册表。通过接收参数为 symbol 类型,返回该 symbol 对应的字符串键,如果查询不到则返回 undefined
let s = Symbol.for('nanlv');
console.log(Symbol.keyFor(s)); // nanlv
console.log(Symbol.keyFor(s2)); // 报错 TypeError: s2 is not a symbol
Symbol.keyFor 仅对 Symbol.for() 方法创建的 symbol 实例才可以查找到,如果是 symbol()方法创建将返回 undefined。
使用 symbol 作为属性
let sym = Symbol();
let obj = {
[sym]: "value"
};
console.log(obj[sym]); // "value"
symbol 属性是对内存中符号的一个引用,所以无法通过 Object.keys
和Object.getOwnPropertyNames
返回,但是可以使用 Object.getOwnPropertySymbols
方法来返回对象所有的 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
作用域排除在外。