ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。
基本用法
let sy = Symbol("KK"); console.log(sy); // Symbol(KK) typeof(sy); // "symbol" // 相同参数 Symbol() 返回的值不相等 let sy1 = Symbol("KK"); sy === sy1; // false
使用场景
1、作为属性名
let sy = Symbol("key1"); // 写法1 let syObject = {}; syObject[sy] = "kk"; console.log(syObject); // {Symbol(key1): "kk"}
Symbol类型的key是不能通过Object.keys()
或者for...in
来枚举的,它未被包含在对象自身的属性名集合(property names)之中。所以,利用该特性,我们可以把一些不需要对外操作和访问的属性使用Symbol来定义。
let obj = { [Symbol('name')]: '小王', age: 18, title: 'Engineer' } Object.keys(obj) // ['age', 'title'] for (let p in obj) { console.log(p) // 分别会输出:'age' 和 'title' } Object.getOwnPropertyNames(obj); // ['age', 'title'] getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
当使用JSON.stringify()
将对象转换成JSON字符串的时候,Symbol属性也会被排除在输出内容之外:
JSON.stringify(obj) // {"age":18,"title":"Engineer"}
如何获取Symbol
// 使用Object的API
Object.getOwnPropertySymbols(obj) // [Symbol(name)]
// 使用新增的反射API
Reflect.ownKeys(obj) // [Symbol(name), 'age', 'title']
2、定义常量
const COLOR_RED = Symbol("red");
Symbol.for()
通常情况下,我们在一个浏览器窗口中(window),使用Symbol()
函数来定义和Symbol实例就足够了。但是,如果你的应用涉及到多个window(最典型的就是页面中使用了<iframe>
),并需要这些window中使用的某些Symbol是同一个,那就不能使用Symbol()
函数了,因为用它在不同window中创建的Symbol实例总是唯一的,而我们需要的是在所有这些window环境下保持一个共享的Symbol。这种情况下,我们就需要使用另一个API来创建或获取Symbol,那就是Symbol.for()
,它可以注册或获取一个window间全局的Symbol实例:
let yellow = Symbol("Yellow"); //Symbol(Yellow) let yellow1 = Symbol.for("Yellow"); //Symbol(Yellow) console.log(yellow === yellow1); // false let yellow2 = Symbol.for("Yellow"); console.log(yellow1 === yellow2); // true
Symbol.keyFor()
Symbol.keyFor() 返回一个已登记的 Symbol 类型值的 key ,用来检测该字符串参数作为名称的 Symbol 值是否已被登记。
let yellow1 = Symbol.for("Yellow"); Symbol.keyFor(yellow1); // "Yellow"