新增特性
Symbol
当普通的字符串形式没有办法锁定唯一的一个物件时,想要锁定该物件需要给定很多提示内容
在计算机中也存在类似的问题,如:在前后台中,有一块区域来存储我们的数据,这个空间中会有很多的业务数据,如果使用字符串去存放数据,可能会发生重名的问题,后面加入的字符串会覆盖前面的字符串,通常,前后台会添加前缀进行一个约束,使用symbol可以完美的解决这个问题,它可以让我们的值永远是唯一的
描述
let hd = Symbol();
console.log(typeof hd); // 结果显示 Symbol
// 不同变量声明的Symbol,是不相等的
let edu = Symbol();
console.log( hd == edu ) // 结果显示false
Symbol
不是普通对象,不能将其当普通对象进行使用,可以将其当成一个永远不会重复的字符串
可以在使用Symbol
声明的时候添加描述:
let hd = Symbol("这是内容描述");
console.log(hd); // 结果显示:Symbol(这是内容描述)
console.log(hd.description); // 结果显示:这是内容描述
通过Symbol.for()
声明变量,系统会在内存中对变量的描述进行一个记录,下一次再这么通过描述进行定义时,系统会查找之前是否有声明过这样的Symbol
,如果声明过,就会将这个Symbol
拿过来:
let hd = Symbol.for("这是内容描述");
let edu = Symbol.for("这是内容描述");
console.log( hd == edu ) // 结果显示true
所以,一个Symbol
如果反复被使用的话,可以通过Symbol.for()
进行定义(普通情况定义通过这种方法是拿不到描述的,只会返回undefined
,因为通过Symbol.for()
定义,是在全局中进行一个保存)
// 通过Symbol.for()获取描述
let hd = Symbol.for("这是内容描述");
console.log(Symbol.keyFor(hd)); // 结果显示:这是内容描述
通过同一个key
进行Symbol
的声明时,是不会重复创建的,会引用第一次定义的Symbol
如果用传统Symbol
方式进行同一个描述内容的声明时,会一直重复声明
使用
// 学生成绩统计,如果有重名的同学
let grade = {
李四: {js: 100, css: 88},
李四: {js: 90, css: 90}
};
consloe.log(grade) // 这个时候就只会打印一个李四的数据:{李四: {js: 90, css: 90}}
因为两个key
是重复的,所以上面就只会显示一个李四,而且是下面这一个
所以,希望以名字作为数据结构时,这样的key
会出现问题
// 通过字符串方式同理
let user1 = "李四";
let user2 = "李四";
let grade = {
[user1]: {js: 100, css: 88},
[user2]: {js: 90, css: 90}
};
consloe.log(grade) // 这个时候就只会打印一个李四的数据:{李四: {js: 90, css: 90}}
为了解决上述的问题,主要通过以下的几种方式:
// 通过Symbol的方式
let user1 = {
name: "李四",
key: Symbol(),
};
let user2 = {
name: "李四",
key: Symbol(),
};
let grade = {
[user1.key]: {js: 100, css: 88},
[user2.key]: {js: 90, css: 90}
};
consloe.log(grade) // 这样就显示所有同学的信息
console.log(grade[user1.key]); // 获取第一个李四的成绩 结果显示:{js: 100, css: 88}
在缓存容器中的使用
web
开发前后端分离,前端是模块化,组件化的,想要独立的模块进行共享一些数据,一般我们会将共享的数据放到容器池(缓存)中,放入共享池的时候,如果使用字符串的形式,就可能会出现重名的情况
其他语法
let data = Symbol("这是一个Symbol类型");
let hd = {
name: "jlc",
[data]: "24"
};
for(const key in hd){
console.log(key);
}
// 结果显示为 name
for in
读取key
时,只能读取前面的,Symbol
类型的读取不到,该类型类似对象中的私有属性(受保护的)
// 如果一定要遍历Symbol中的内容,可以使用以下的方法,但是普通属性又遍历不到了
for(const key of getOwnPropertySymbols(hd)){
console.log(key);
}
// 结果显示:Symbol(这是一个Symbol类型)
// 遍历所有属性的方法
for(const key of Reflect.ownKeys(hd)){
console.log(key);
}
// 结果显示:
name
Symbol(这是一个Symbol类型)