一.Symbol的介绍:
Symbol 是一种特殊的、不可变的数据类型,可以作为对象属性的标识符使用。Symbol 对象是一个 symbol primitive data type 的隐式对象包装器。
symbol 数据类型是一个原始数据类型。
eg:
let obj = {
a: 1
}
等同于对象格式:
Object {
key: value
}
在ES5的时代,对象的key只能是字符串String类型。把key改成其他数据类型?ES就指定了一个新的数据类型:Symbol。
二.使用:
1.Symbol(description) //description是可选的
eg:
//创建一个Symbol
const name = Symbol();
const name1 = Symbol('sym1');
console.log(name, name1) // Symbol() Symbol(sym1)
2.注意:Symbol不能使用new关键字
const name = new Symbol(); //错误的示范。
//Symbol is not a constructor
//使用:
const name1 = Symbol('sym1');
console.log(name1);// Symbol(sym1)
3.在所有使用可计算属性名的地方,都能使用Symbol类型。比如在对象中的key。
eg:
const name = Symbol('name');
const obj = {
[name]: "张三"
}
console.log(obj[name]) // 张三
4.使用Object.defineProperty()和Object.defineProperties()方法。这2个方法是对象的方法,但是作为Symbol类型key,也不影响使用。
// 设置对象属性只读。
Object.defineProperty(obj, name, {writable: false})
三.Symbol全局共享:
Symbol有点特殊,在js文件中定义的Symbol,并不能在其他文件直接共享。
ES6提供了一个注册机制,当你注册Symbol之后,就能在全局共享注册表里面的Symbol。Symbol的注册表和对象表很像,都是key、value结构,只不过这个value是Symbol值。
(key, Symbol)
语法:
Symbol.for() //只有一个参数
还有一个方法是获取注册表的Symbol。
语法:
Symbol.keyFor() //只有一个参数,返回的是key
从注册表获取全局共享的Symbol:
let name = Symbol.for('name');
let name1 = Symbol.for('name1');
let name2 = Symbol.for('name2');
console.log(Symbol.keyFor(name)) // name
console.log(Symbol.keyFor(name1)) // name1
console.log(Symbol.keyFor(name2)) // name2
注意:如果要防止Symbol命名重复问题,可以加上前缀。如:XXX.name
四.Symbol与类型强制转换:
Symbol不支持这种转换
let a = Symbol('a');
console.log(typeof a);
console.log(a + ' haha') // Cannot convert a Symbol value to a string
五.Symbol检索:
在对象中获取字符串的key时,可以使用Object.keys()或Object.getOwnPropertyNames()方法获取key,但是使用Symbol做key是,你就只能使用ES6新增的方法来获取了。
eg:
let a = Symbol('a');
let b = Symbol('b');
let obj = {
[a]: "123",
[b]: 45
}
const symbolsKey = Object.getOwnPropertySymbols(obj);
for(let value of symbolsKey) {
console.log(obj[value])
}
//"123"
//45