Symbol
18888628835 opened this issue · 1 comments
Symbol
Symbol 首先可以解决对象属性名重复的问题,由于对象的属性名是字符串,很容易出现重复,Symbol 会产生独一无二的类字符串的数据类型,所以不会产生冲突。
Symblol 需要如何创建呢?由于生成的是简单数据类型,不是一个对象,所以 ES6规定生成 Symbol 不能使用 new 关键字。我们可以这样生成
const s=Symbol()
console.log(typeof s)//"symbol"
const s=Symbol()
console.log(s)//Symbol()
const b=Symbol()
console.log(b)//Symbol()
s===b //false
如果直接打印,会发现返回的都是 Symbol()
,所以我们可以传入一个参数来添加描述 description。
const s=Symbol('s')
const b=Symbol('b')
undefined
s
//Symbol(s)
b
//Symbol(b)
也可以传一个对象,当传入一个对象时,会自动在内部调用 toString 方法
const CustomToString={
toString(){
return 'abc'
}
}
const a=Symbol(CustomToString)
console.log(a)//Symbol(abc)
由于传入的参数只是描述,所以即使描述是一样的,生成的 Symbol 值也是不相等的。
Symbol('abc')===Symbol('abc')
//false
description
当我们需要区分 Symbol 时,可以通过传入的参数作为其描述来区分 Symbol,那么如果想获取其描述呢?
我们有两种方法:
- 第一种调用 toString 方法
let a=Symbol('a')
a.toString()
"Symbol(a)"
- 第二种使用 description 属性
let b=Symbol('b')
b.description
"b"
Symbol注意点
Symbol 作为对象的属性名时保证不会出现同名属性,但是我们如果想要读取属性,不能直接用点来读取,而要使用中括号读取。
let a={}
let sym=Symbol()
a.sym='123'
a.sym //'123'
a[sym] //undefined
这是因为当使用点的形式来读取对象的属性时,点后面的是字符串,所以实际上这是相等的
a['sym']===a.sym
而 Symbol 属性被保存在 sym 这个变量名中,如果需要引用,只能这样写
a[sym]===a['sym'] //false
a[sym]='456'
a[sym] //'456'
Symbol 的使用场景
知道了 Symbol 的优点,那么究竟 Symbol 有什么用途?
当我们需要一个独一无二的东西且这个东西并不重要时可以使用,比如,当我从后端拿来数据,但是发现需要渲染到页面上的数据没有唯一的 key,这时候不一定需要 uuid,也可以自己给 key 生成一个 symbol 值。
还有一个用途是可以消除魔术字符串。
魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。风格良好的代码,应该尽量消除魔术字符串,改由含义清晰的变量代替。
比如,当我使用 Redux 时,我可能会这样写
//页面1
dispatch({type:'add',payload})
//页面2
dispatch({type:'add',payload})
...
可以看到上面的add 就是魔术字符串。有可能很多个组件都会写这样的字符串,仔细看其实这个字符串也不是很重要,我们只是需要这个逻辑。
那么我可以这样写
//config
export const hashMap={
ADD:Symbol(),
REMOVE:Symbol(),
}
//页面1
dispatch({type:hashMap.ADD,payload})
//页面2
dispatch({type:hashMap.REMOVE,payload})
...
作为属性名的注意要点
Symbol 作为属性名,遍历对象的时候,该属性不会出现在for...in
、for...of
循环中,也不会被Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回。
let a=Symbol()
obj[a]='123'
obj.b='456'
for(let i in obj){
console.log(i)
}
// '456'
目前关于 Symbol,实际应用的不是很多,就先介绍到这里,如果还有兴趣了解 Symbol 的 API,可以参见
Symbol
Symbol 其实出现在 JavaScript 的很多地方。
可以看看掘金上这篇文章:https://juejin.cn/post/6844903511960846350#heading-15