Symbol类型的应用
新的基础数据类型,Symbol是由ES6引入的一种新特性,功能类似标识唯一性的ID。记住,每个Symbol实例都是唯一的。
场景1:使用Symbol作为对象属性名-key
const PROP_NAME = Symbol("name");
const PROP_AGE = Symbol("age");
let obj = {
[PROP_NAME]: "菠萝油王子",
job: "fornt-end-developer"
}
obj[PROP_AGE] = 18;
obj[PROP_NAME] // "菠萝油王子"
obj[PROP_AGE] // 18
注意⚠:Symbol类型的key是不能通过object.keys()
或者for...in
来枚举,它未被包含在对象自身的属性名集合(property names)之中。
同时,JSON.stringify()
将对象转换成json字符串的时候,Symbol类型的属性也会被排除在外;
可以利用这一特点来更好的设计我们的数据对象,让“对内操作”和“对外选择性输出”变得更加优雅
取值该方式定义的对象属性,指定API:
// 使用Object的API,该api只输出Symbol类型的属性
Object.getOwnPropertysmbol(obj) // [Symbol(name), Symbol(age)]
// 反射API
Reflect.ownKeys(obj) // ["job", Symbol(name), Symbol(age)]
场景2:替代常量
通常需要一些常量是唯一的,常量一多,就要取些复杂和语义化的名字,现在可以用symbol来处理。
// 保证常量的值是唯一的
const NAME = Symbol()
const AGE = Symbol()
const TITLE = Symbol()
场景3:定义类的私有属性/方法
// 文件a.js
const PASSWORD = Symbol();
class Login {
constructor(username, password) {
this.username = username;
this[PASSWORD] = password;
}
checkPassword(pwd) {
return this[PASSWORD] === pwd;
}
}
export default Login;
类和模块化机制:
// 文件b.js
import Login from "./a";
const login = new Login("admin","123456");
login.checkPassword("123456"); // true
login.PASSWORD; // undefined
login["PASSWORD"]; // undefined
由于Symbol常量PASSWORD被定义在a.js所在的模块中,外面的模块获取不到这个Symbol,也不可能再创建一个一模一样的Symbol出来(因为Symbol是唯一的),因此这个PASSWORD的Symbol只能被限制在a.js内部使用,所以使用它来定义的类属性是没有办法被模块外访问到的,达到了一个私有化的效果。
微信公众号:1芒果Mango
**