Symbol类型的应用

新的基础数据类型,Symbol是由ES6引入的一种新特性,功能类似标识唯一性的ID。记住,每个Symbol实例都是唯一的。

场景1:使用Symbol作为对象属性名-key

  1. const PROP_NAME = Symbol("name");
  2. const PROP_AGE = Symbol("age");
  3. let obj = {
  4. [PROP_NAME]: "菠萝油王子",
  5. job: "fornt-end-developer"
  6. }
  7. obj[PROP_AGE] = 18;
  8. obj[PROP_NAME] // "菠萝油王子"
  9. obj[PROP_AGE] // 18

注意⚠Symbol类型的key是不能通过object.keys()或者for...in来枚举,它未被包含在对象自身的属性名集合(property names)之中。
同时,JSON.stringify()将对象转换成json字符串的时候,Symbol类型的属性也会被排除在外

可以利用这一特点来更好的设计我们的数据对象,让“对内操作”和“对外选择性输出”变得更加优雅

取值该方式定义的对象属性,指定API:

  1. // 使用Object的API,该api只输出Symbol类型的属性
  2. Object.getOwnPropertysmbol(obj) // [Symbol(name), Symbol(age)]
  3. // 反射API
  4. Reflect.ownKeys(obj) // ["job", Symbol(name), Symbol(age)]

场景2:替代常量

通常需要一些常量是唯一的,常量一多,就要取些复杂和语义化的名字,现在可以用symbol来处理。

  1. // 保证常量的值是唯一的
  2. const NAME = Symbol()
  3. const AGE = Symbol()
  4. const TITLE = Symbol()

场景3:定义类的私有属性/方法

  1. // 文件a.js
  2. const PASSWORD = Symbol();
  3. class Login {
  4. constructor(username, password) {
  5. this.username = username;
  6. this[PASSWORD] = password;
  7. }
  8. checkPassword(pwd) {
  9. return this[PASSWORD] === pwd;
  10. }
  11. }
  12. export default Login;

类和模块化机制:

  1. // 文件b.js
  2. import Login from "./a";
  3. const login = new Login("admin","123456");
  4. login.checkPassword("123456"); // true
  5. login.PASSWORD; // undefined
  6. login["PASSWORD"]; // undefined

由于Symbol常量PASSWORD被定义在a.js所在的模块中,外面的模块获取不到这个Symbol,也不可能再创建一个一模一样的Symbol出来(因为Symbol是唯一的),因此这个PASSWORD的Symbol只能被限制在a.js内部使用,所以使用它来定义的类属性是没有办法被模块外访问到的,达到了一个私有化的效果。
微信公众号:1芒果Mango
qrcode_for_gh_0e7f620a68c0_258.jpg**