symbol
symbol是ES6中一种新的数据类型。平时很少会用到,今天特意了解一下。或许某天遇到什么需求可以派上用场。
首先它是一种新的数据类型
使用方法
let e = Symbol()
这样便创建了一个Symbol实例。如果我们用typeof来检查它,会返回symbol,一个新的类型。
typeof e //symbol
它是唯一的
每个symbol实例都是唯一的。
let s1 = Symbol()let s2 = Symbol('another symbol')let s3 = Symbol('another symbol')s1 === s2 // falses2 === s3 // false
对象属性
正因为他是唯一的。我们可以把他做对象的特定属性。
const PROP_NAME = Symbol()const PROP_AGE = Symbol()let obj = { [PROP_NAME]: "属性" [PROP_AGE] = 18}obj[PROP_NAME] // '属性'obj[PROP_AGE] // 18
对象中的Symbol不能普通方法列举
Symbol类型的key是不能通过Object.keys()或者for...in来枚举的,它未被包含在对象自身的属性名集合(property names)之中。
let obj = { [Symbol('name')]: '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']
所以可以用Symbol存放一些不需要对外操作的属性。
枚举Symbol
Symbol有自己特定的枚举方法。
// 使用Object的APIObject.getOwnPropertySymbols(obj) // [Symbol(name)]// 使用新增的反射APIReflect.ownKeys(obj) // [Symbol(name), 'age', 'title']
场景
按他的特性来说能我遇到过需要Symbol用场景确实不是很多。他主要是可以通过它的唯一性代替常量。
// 原来情况export const FECTH_PROJECT_ROOT = 'fetchProjectRoot'export const DELETE_FILE = 'deleteFile'let obj={ [FECTH_PROJECT_ROOT]:{ }, [DELETE_FILE]:{ }}
可以改用Symbol
export const FECTH_PROJECT_ROOT = Symbol();export const DELETE_FILE = Symbol();let obj={ [FECTH_PROJECT_ROOT]:{ }, [DELETE_FILE]:{ }}
或者switch等,类似的情况。