JS中的
Symbol
是在ES6中出现的一种新的数据类型,它属于原始数据类型,平时对它的使用场景也是一知半解,现在有时间写篇文章,了解学习一下。
Symbol
Symbol
是ES6中的一种新的基本数据类型,它表示独一无二的值。
我们知道在 JS 的 Object数据类型中的key它只允许是字符串或者是symbol,在某些情况下,我们需要确保属性名是唯一的,这时候就可以使用Symbol
类型来创建一个全局唯一的字符,避免属性名或者方法名发生冲突。
我们可以通过 Symbol() 来创建一个Symbol类型的值
//可以通过 Symbol() 来创建一个Symbol类型的值
const mykey = Symbol()
Symbol
值可以作为对象的属性名、类的静态变量、对象的方法名等等,如下所示 ⬇
//可以作为对象的属性名
const obj = {}
const mykey = Symbol()
obj[mykey] = 'mySymbol'
console.log(obj.mykey) // 输出mySymbol
// 类的静态变量
class myClass{
static [mykey] = 'mySymbol'
}
console.log(MyClass[mykey]) // 输出mySymbol
//作为对象的方法名
const myKey1 = Symbol()
const Obj = {
[mykey1]: function() {
console.log('mySymbol')
}
}
Obj[mySymbol]() // 输出mySymbol
需要注意的是,由于 Symbol
类型的值是唯一的,即使我们创建两个相同的 Symbol
值,它们也是不相等的 ⬇
const symbol1 = Symbol("foo")
const symbol2 = Symbol("foo")
console.log(symbol1 === symbol2) // 输出false
// 你可以使用 Symbol.for('xx')查找全局注册到的symbol类型属性并复用,此方法有查找和创建Symbol类型的操作
const a = Symbol.for('hello')
const b = Symbol.for('hello')
console.log(a === b) // 输出true
Symbol
类型的值是无法被遍历的,因此不会出现在 for…in 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames() 以及 JSON.stringify() 等方法获取到。
这里也是联想到一个小知识 ⬇
JSON.stringify()我们可以用来做深拷贝,但是由于Symbol
属性是无法被遍历的,所以使用JSON.stringify()完成深拷贝是无法拷贝的Symbol
类型的值的,除此之外也无法拷贝到值为Function和undefined、日期、正则等的属性。这也是用这种方法做深拷贝的缺陷。
// 简单测试一下
const mySymbol = Symbol()
let obj = {
[mySymbol]: '66',
arr: [1,2,3,5,[10,12]],
tryUndefine: undefined,
myFunction: function(){
console.log(666)
},
myName: 'cxx',
myDate: new Date(),
regex: /hello/
}
console.log(obj)
let objStr = JSON.stringify(obj)
console.log(objStr)
let res = JSON.parse(objStr)
console.log(res)
言归正传,上面说到Symbol
类型属性不能被for…in…遍历出来,如果需要遍历一个对象的所有属性,可以使用 Reflect.ownKeys() 方法获取所有属性名(包括 Symbol 类型的属性名)。
const mySymbol = Symbol()
const mySymbol2 = Symbol()
let obj = {
a: 'hello',
b: [1,2,3],
[mySymbol]: '666',
[mySymbol2]: '888'
}
for(let key in obj){
console.log(obj[key])
}
console.log('-----------分界线------------')
for(let item of Reflect.ownKeys(obj)){
console.log(obj[item])
}
文章有问题之处还望评论斧正!