Symbol
Symbol是JS引入的一种新的数据类型,表示独一无二的值,在此之前的数据类型有undefined、null、布尔值Boolean、字符串String、数值Number、对象Object。
1.不能进行计算
2.显示调用toString()
3.隐式转换boolean
4.防止覆盖
5.for in 遍历问题
6.常量
一、不能进行计算
//symbol是独一无二值,所以声明两个相同的symbol他们也是相等的
let s1 = Symbol();
let s2 = Symbol();
console.log(s1==s2,s1===s2) // false false
//symbol不能进行计算
console.log(s1 + "111") // 报错
console.log(s1 > 1) // 报错
二、显示调用toString()
可以使用toString()把symbol转换为字符串
let s1 = Symbol();
console.log(s1.toString()) // Symbol()
三、隐式转换boolean
在条件判断时会自动转换为true
let s1 = Symbol();
if(s1){
console.log("111") // 111
}
四、防止覆盖
在实际开发过程在,自己写了一个库,但是给别人使用时,别人想添加新的属性或者方法,但不巧和你的重名,此时你属性就被覆盖掉了。
let obj = { // 假设obj是一个方法库
name:"starry",
age:18
}
obj.name = "A"
console.log(obj.name) // A 被覆盖了
使用symbol就不要担心这样的问题了
let name = Symbol()
let obj = {
[name]:"starry",
age:18
}
obj.name = "A"
console.log(obj) // {age: 18, name: 'A', Symbol(): 'starry'}
console.log(obj.name,obj[name]) // A starry
obj[name] = "b" //当然如果这样写还是能覆盖,但是这样就属于没事找事了
console.log(obj[name]) // b
来优化一下
let key = {
name:Symbol(),
age:Symbol(),
text:Symbol()
}
let obj = {
[key.name]:"starry",
[key.age]:18,
[key.text](){
console.log("测试")
}
}
obj.name = "111"
console.log(obj)
obj[key.text]()
但是这样也带来了一个问题,在控制台查看的时候全是Symbol,这个时候Symbol的传参就发挥作用了,相当于给Symbol一个标记
let key = {
name:Symbol("name"),
age:Symbol("age"),
text:Symbol("text")
}
let obj = {
[key.name]:"starry",
[key.age]:18,
[key.text](){
console.log("测试")
}
}
obj.name = "111"
console.log(obj)
obj[key.text]()
五、for in 遍历问题
let key = {
name: Symbol("name"),
age: Symbol("age"),
text: Symbol("text")
}
let obj = {
[key.name]: "starry",
[key.age]: 18,
[key.text]() {
console.log("测试")
}
}
obj.name = "111"
for (let i in obj) {
console.log(i) // 只有一个普通属性 name
}
console.log(Object.getOwnPropertySymbols(obj)) // [Symbol(name), Symbol(age), Symbol(text)] 只有symbol类型的属性
console.log(Reflect.ownKeys(obj)) // ['name', Symbol(name), Symbol(age), Symbol(text)] 全部都有
最后一种方式就可以通过forEach拿到全部值
Reflect.ownKeys(obj).forEach(item =>{
console.log(item,obj[item])
})
六、常量
这个主要用于规范输入,比如以下代码,我们希望输入A来执行函数,但是直接输入1同样会执行函数
const A = 1
function text(type){
switch(type){
case A: console.log("1111")
}
}
text(A) // 1111
text(1) // 1111
这个时候使用symbol就可以使输入唯一
const A = Symbol()
function text(type){
switch(type){
case A: console.log("1111")
}
}
text(A) // 1111 只有输入A才会执行