数据类型
ECMAScript有6种简单数据类型(内存直接存的值),分别是Undefined,Null,Boolean,Number,String,Symbol,还有一种复杂的数据类型(内存存的是引用地址)=>Object(对象)。
而我们接下来要讲的是ES6中新增的一个基本数据类型——Symbol
Symbol
在我们与别人合作的时候,我们不知道别人会在某个对象中定义了什么属性,而我们往里面添加同名的属性,很容易会造成冲突,将内部的属性覆盖掉,这是我们不想要的结果,而 Symbol 能够解决这样的问题
Symbol 数据类型是一种原始数据类型,表示独一无二的值。该类型的性质在于这个类型的值可以用来创建匿名的对象属性。
- Symbol值是通过Symbol函数来生成的,生成后可以作为属性名;
- 也就是在ES6中,对象的属性名可以使用字符串,也可以使用Symbol值
// ES6之前, 对象的属性名(key) 都是 字符串
var obj = {
name: "a", // 属性名name相当于'name'
}
// 虽然首字母大写,但它仍是一个函数
const s1 = Symbol()
const s2 = Symbol()
console.log(s1 === s2) // false
Symbol值作为key的用法
- 在定义对象字面量时使用
const obj = {
[s1]: "abc",
[s2]: "cba"
}
- 新增属性
// 新增属性
obj[s3] = "nba"
//Object.defineProperty方式来新增/定义
const s4 = Symbol()
Object.defineProperty(obj, s4, {
enumerable: true,
configurable: true,
writable: true,
value: "mba"
})
- 获取obj 中用 Symbol 值作为 key 的属性
console.log(obj[s1], obj[s2], obj[s3], obj[s4])
// 注意: 不能通过.语法获取
// console.log(obj.s1)
注意:使用Symbol作为key的属性名,在遍历Object.keys等中是获取不到这些Symbol值,需要Object.getOwnPropertySymbols来获取所有Symbol的key
var obj = {};
var a = Symbol('a');
var b = Symbol('b');
obj[a] = 'Hello';
obj[b] = 'World';
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols);
// [Symbol(a), Symbol(b)]
扩:Symbol.for(key)/Symbol.keyFor(symbol)
如果我们希望使用同一个 Symbol 值,可以使用 Symbol.for
const sa = Symbol.for("aaa")
const sb = Symbol.for("aaa")
console.log(sa === sb) // true
Symbol.keyFor 方法返回一个已登记的 Symbol 类型值的 key
const sa = Symbol.for("aaa")
const key = Symbol.keyFor(sa)
console.log(key) // aaa
参考资料和扩展:
冴羽的博客——ES6 系列之模拟实现 Symbol 类型:https://github.com/mqyqingfeng/Blog/issues/87