Symbol 概述
Symbol 值表示唯一的标识符。
创建时,不需要 new,可以指定描述作为 Symbol 名。
let id = Symbol("idHere");
每个存在的 Symbol 都是互不相同的,即使 Symbol 名相同。因为 Symbol 名只是一个标签。
let s1 = Symbol("路由器");
let s2 = Symbol("路由器");
s1 == s2; // false
Symbol 不会被自动转换为其他基本类型的值。如果想要转为 string,需要显示调用 symbol.toString()
或者 symbol.description
属性获取 Symbol 实例的 Symbol 名。
Symbol 作为隐藏的属性
Symbol 作为对象的属性名时,一般的访问对象属性的代码看不到这个属性。
利用这个特点,可以将一些值绑定在你无法完全控制的对象上,例如第三方的对象上。第三方的代码根本不会看到这个属性。
// 假设 user 为第三方代码创建的对象
let id = Symbol('id');
user[id] = "12334";
Symbol 属性会在 for...in
循环和 Object.keys()
中跳过
let obj = {
... age: 99,
... action: function() {},
... [id]: 2021,
... }
for (let k in obj) { console.log(k) }
Object.keys(obj)
输出 age action
和 [ 'age', 'action' ]
,并没有 Symbol。
克隆对象时,Object.assign
** 可以看到 ** 并复制 Symbol 属性。
let b = Object.assign({},obj);
b // { age: 99, action: [Function: action], [Symbol(id)]: 2021 }
全局 Symbol
虽然创建出来的 Symbol 互不相同,但是,可以使用全局 Symbol 注册表,维护 Symbol 实例,保证使用同一个 key
获得的 Symbol 都是相同的。
注册表内的 Symbol 就是全局 Symbol,可以在所在应用的代码中随处访问。
Symbol.for(key)
Symbol.for(key)
可以从全局 Symbol 注册表中读取返回(不存在则新建)一个 Symbol。
let id = 'id-123';
let user = {
[Symbol.for(id)]: "我是 ID",
}
user[Symbol.for(id)]; // "我是 ID"
Symbol.keyFor(sumbol)
由 Symbol 注册表的 symbol 实例其 symbol 名
Symbol.keyFor(Symbol.for(id)); // 'id-123'
如果没有在全局注册表中,则返回 undefined
let localSymbol = Symbol('id-0');
Symbol.keyFor(localSymbol); // undefined
内置 Symbol
JavaScript 内部有很多 “系统” Symbol,我们可以使用它们来微调对象的各个方面。
这里不表。Symbol.for("Symbol.asyncIterator"); => Symbol(Symbol.asyncIterator)
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论。