扫码关注公众号,获取更多内容
目录
一、Symbol是什么?
ES6增加了一种新的数据类型Symbol,表示独一无二的值,最大的用法是用来定义对象的唯一属性。
二、基本用法
Symbol可以接受一个字符串作为参数,下面的例子表明了Symbol的唯一性(不论参数是否相同,Symbol都是唯一的)
let sy1 = Symbol('sy')
let sy2 = Symbol('sy')
console.log(sy1) // 输出 Symbol(sy)
console.log(typeof sy1) // 输出 symbol
console.log(sy1 === sy2) // 输出 false
三、使用场景
1、作为属性名
每一个Symbol的值都是不相等的,所以symbol作为对象的属性名,可以保证属性不重名
let sy = Symbol('key1')
// 写法1
let obj = {}
obj[sy] = 'eueh'
console.log(obj) // 输出 Symbol(key1): "eueh"
// 写法2
let obj2 = {[sy]: 'eueh2'}
console.log(obj2) // 输出 Symbol(key1): "eueh2"
// 写法3
let obj3 = {}
Object.defineProperty(obj3, sy, {value: 'eueh3'})
console.log(obj3) // 输出 Symbol(key1): "eueh3"
Symbol作为对象属性名时不能用 . 运算符,要用方括号,因为 . 运算符后面是字符串,所以取到的是字符串sy属性,而不是Symbol值sy属性。
let obj4 = {}
obj4[sy] = 'eueh4'
console.log(obj4[sy]) // 输出 eueh4
console.log(obj4.sy) // 输出 undefined,因为没有sy这个key,key是Symbol('key1')
注意点:
Symbol值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问,但不会出现在for...in、for...of的循环中,也不会被Object.keys()、Object.getOwnPropertyNames()返回。如果要读取一个对象的Symbol属性,可以通过Object.getOwnPropertySymbols()和Refiect.ownKeys()取到。
let obj5 = {}
obj5[sy] = 'eueh5'
for (let i in obj5) {
console.log(i) // 无输出
}
console.log(Object.keys(obj5)) // 输出 []
console.log(Object.getOwnPropertySymbols(obj5)) // 输出 [Symbol(key1)]
console.log(Reflect.ownKeys(obj5)) // 输出 [Symbol(key1)]
2、定义常量
常规的定义常量的方式如下,但是所需要定义的常量比较多的时候,就可能在设置唯一值时出现错误。
const a = 'a'
const b = 'b'
使用Symbol定义常量,可使常量值不重复
const a2 = Symbol('a2')
const b2 = Symbol('b2')
3、定义某个类的私有属性或方法
在不同文件对于类的调用中,有些私有的属性和方法不想对外允许访问,这个时候就可以利用Symbol()来定义。
// 这个是a文件内定义的Login类:
const password = Symbol()
class Login {
constructor(username, password) {
this.username = username
this[password] = password
}
checkPassword(pwd) {
return this[password] === pwd
}
}
export default Login; // 对外暴露了login方法
// 这个是在b文件内调用a文件中的方法:
const login = new Login('admin', '123456')
login.checkPassword('123456') // true
login.password // 无法访问
login[password] // 无法访问
login["password"] // 无法访问
四、symbol.for()
Symbol.for()类似单例模式,首先会在全局搜索被登记的Symbol中是否有该字符串参数作为名称的Symbol值,如果有即返回该Symbol值,没有则新建并返回一个以该字符串参数为名称的Symbol值,并登记在全局环境中供搜索。
let yellow = Symbol("Yellow");
let yellow1 = Symbol.for("Yellow");
yellow === yellow1; // false
let yellow2 = Symbol.for("Yellow");
yellow1 === yellow2; // true
五、Symbol.keyFor()
Symbol.keyFor() 返回一个已登记的 Symbol 类型值的 key ,用来检测该字符串参数作为名称的 Symbol 值是否已被登记。
let yellow1 = Symbol.for("Yellow");
Symbol.keyFor(yellow1); // "Yellow"