开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天 点击查看详情
Symbol出现的原因
ES5中,对象的属性名都是字符串,容易造成属性名称冲突,于是,在ES6中引入原始数据类型Symbol ,表示独一无二 的值。
即 ES6中的Symbol是一种新的基本数据类型,它是一种唯一且不可变的值,用于创建对象属性的唯一标识符
特性
- Symbol的值是唯一且不可变的,即使创建多个相同描述符的Symbol,它们也是不同的值。
- Symbol是原始类型,可以通过typeof运算符来检测它们。
- Symbol可以作为对象属性的键名,用于避免属性名冲突。
- Symbol创建的属性可以通过Object.getOwnPropertySymbols()方法获取,而不是Object.keys()方法。
let s = Symbol();
typeof s // "symbol"
typeof运算符的结果,表明变量s是 Symbol 数据类型,而不是字符串之类的其他类型
使用限制
- Symbol不能被New操作符调用,因为它不是构造函数。
- Symbol不能被强制转换为字符串或数字类型,因为它们是原始类型,而不是对象。
- Symbol不能被迭代,因为它们不是可迭代的数据类型。
因此,我们不能使用for...of或forEach等迭代器循环Symbol。如果我们需要遍历对象的Symbol属性,可以使用Object.getOwnPropertySymbols()方法来获取Symbol属性,并手动遍历它们。
使用-例子
Symbol 的值是通过Symbol 函数生成的
对象属性-在对象字面量中使用 Symbol 作为键
不能使用点语法访问以 Symbol 为键的属性,必须使用方括号来访问属性
let id = Symbol("id");
let obj = {
[id]: 1
}
console.log(obj[id])
常见的对象检查功能会跳过 Symbol
- 在 JavaScript 最常见的对象检查功能(例如 for-in 循环)中会跳过 Symbol 属性
- 在 Object.keys(obj) 和 Object.getOwnPropertyNames(obj) 中也将忽略作为属性键的 Symbol
- 使用 JSON.stringify() 时,将忽略对象的 Symbol 属性
Symbol 值作为属性名,遍历对象的时候,该属性不会出现在
for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回
优缺点:
- 优点:Symbol可以避免属性名冲突,使代码更加安全和可读。
- 缺点:使用Symbol可能会使代码变得更加难懂和复杂,因为它们是不可见的,且不能被序列化和传输。
Symbol.for()
当希望重新使用同一个 Symbol 值,Symbol.for()方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局
Symbol.for()与Symbol()这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。
Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值
Symbol.keyFor()
返回一个已登记的 Symbol 类型值的key