是什么?
Symbol 是 ES6 新增的基本数据类型–符号,它具有唯一性、不可变性。因此能确保对象属性的唯一性,不会发生冲突。
Symbol 和其他基本类型:null、undefined、boolean、number、string的不同是没有对应的包装类和 new 一起使用。
let s = new String('zhangsan')
而 new Symbol() 则会报错:
let s = new Symbol()
// Uncaught TypeError: Symbol is not a constructor
基本用法
创建:
let s = Symbol()
let name = Symbol('name') // 传入字符串作为符号的描述,主要用于调试代码
比较:
let s1 = Symbol()
let s2 = Symbol()
s1 == s2 // false
let s3 = Symbol('name')
let s4 = Symbol('name')
s3 == s4 // false
之前对象的属性只能是字符串类型,现在可以是 Symbol 的实例:
let name = Symbol('name')
let o = {
[name]:'zhangsan'
}
// or
let name = Symbol('name')
let o = {}
o[name] = 'zhangsan'
那相对于字符串类型的优点就是唯一性,不会覆盖已有的属性:比如想对第三方的一个对象 people 添加属性时,如果使用字符串作为属性很有可能会覆盖原有的属性,而使用 Symbol 就算属性名相同也不会:
let id = Symbol("id");
people[id] = "新增值";
全局符号注册表
Symbol 每次创建都是唯一的,那如何复用呢? Symbol.for 就解决了共享和重用问题。
let name = Symbol.for('name') // 第一次时全局注册表不存在则创建并添加到注册表中。
let otherName = Symbol.for('name') // 后续使用相同字符串,先检索全局注册表有就返回,反之创建。
name == otherName // true
我们可以通过 Symbol.keyFor 来反查字符串键:
let name = Symbol.for('name')
Symbol.keyFor(name) // 'name'
使用普通符号:
let name = Symbol('name')
Symbol.keyFor(name) // undefined
对象属性遍历
for…in 会忽略 Symbol:
let id = Symbol("id");
let user = {
name: "John",
age: 30,
[id]: 123
};
for (let key in user) alert(key); // name, age (no symbols)
Object.keys(usr) // ['name','age']
Object.getOwnPropertyNames(user) // ['name','age']
Object.getOwnPropertySymbols(user) // [Symbol(id)]
let clone = Object.assign({}, user);
clone[id] // 123
参考: