背景
在ES6问世之前,JavaScript的基本数据类型只有5种,分别是String(字符串)、Number(数字)、Boolean(布尔)、Undefined(未定义)、Null(空),但是ES6问世后,我们的基本数据类型又新增了两种,分别是Symbol(ES新增)、BigInt(ES10新增)。那新增加这两种基本数据类型是干嘛的呢?有什么作用呢?今天我们们就来好好讲一讲!!
Symbol
什么是Symbol?
Symbol作为基本数据类型的一种,表示独一无二的值,在ES6发布之前,因为对象的键以字符串的形式存在,所以极易引发键名冲突问题,而Symbol的出现正是解决了这个痛点,所以它的使用方式也很简单。
那怎么用Symbol呢?
Symbol() 函数会返回 symbol 类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的 symbol 注册,且类似于内建对象类。
注意:因为是Symbol原始数据类型,不是对象所以他并不支持new语法:"new Symbol()" // TypeError
我们要在调用Symbol()时传入一个字符串当做描述值。Symbol(“描述值”)会返回一个唯一的值
let a = Symbol(“description”)
typeof a
属性名的遍历
Symbol 作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。但是,它也不是私有属性,有一个Object.getOwnPropertySymbols方法,可以获取指定对象的所有 Symbol 属性名。
Object.getOwnPropertySymbols():返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。Reflect.ownKeys():返回所有类型的键名。
let obj = {
[Symbol('my_key')]: 1,
enum: 2,
nonEnum: 3
};
Reflect.ownKeys(obj)
// ["enum", "nonEnum", Symbol(my_key)]
Symbol的使用相对简单,那它的实际是如何应用的呢?
Symbol的实际应用
作为对象的键名(唯一不冲突)
大家肯定都维护过别人写的项目,或者是别人写的代码。因为项目不是我们自己写的。当我们想要给项目里的对象增加一个属性或者方法时,很容易会引起键名重复或者覆盖的问题。这时 Symbol的唯一特性就能很好的帮我们解决这个问题。它可以作为对象的属性的键,并键名避免冲突。
let a = Symbol("a")
let obj = {}
obj[a] = "zayyo"
console.log(obj[a])
- 我们创建了一个Symbol基本数据类型(描述符为a)
- 我们通过obj[]把a这个Symbol类型的值作为对象的键进行赋值定义
注意:我们不能使用.来调用对象的Symbol属性,所以必须使用[]来访问Symbol属性。因为点运算符后面默认跟的是字符串
方便全局调用同一个Symbol
当我们想在不同的地方调用一个已近定义过的
Symbol即全局调用同一个Symbol,可以通过Symbol.for()方法,参数为创建时传入的描述字符串,该方法可以遍历全局注册表中的的Symbol,当搜索到相同描述,那么会调用这个Symbol,如果没有搜索到,就会创建一个新的Symbol。
let s1 = Symbol.for('a');
let s2 = Symbol.for('a');
s1 === s2 // true
- 首先我们用Symbol.for创建了描述符为a的Symbol基本数据类型
- 使用
Symbol.for("a")在全局注册表中寻找描述为a的Symbol
注意:因为Symbol(‘’)生成的标识是唯一的,所以就算()里的描述值是相同的他们最终返回的值也不是相同的。但是Symbol.for()不同,当()里的描述值是相同时,他们返回的值也是相同的。
let S1=Symbol('zayyo')
let S2=Symbol('zayyo')
let S3=Symbol.for('zayyo')
let S4=Symbol.for('zayyo')
console.log(S1===S2)//false
console.log(S3===S4)//true
Symbol.keyFor()
假如我们想逆推,用Symbol.for("a")返回的值去获得()里的描述值又该怎么办呢?
我们可以使用Symbol.keyFor()
let b = Symbol.for("a")
Symbol.keyFor(b) // 'a'
写在最后
伙伴们,如果你觉得我写的文章对你有帮助就给zayyo点一个赞👍或者关注➕都是对我最大的支持。当然你也可以加我微信:IsZhangjianhao,邀你进我的前端学习交流群,一起学习前端,成为更优秀的工程师~
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 19 天,点击查看活动详情