一、使用Symbol作为对象属性名
1、使用symbol作为对象属性名不被Object.key等方式访问
let obj = { [Symbol("name")]:"一斤代码", age:18, title:"Engineer", } console.log(Object.keys(obj)) for(let p in obj){ console.log(p); } console.log(Object.getOwnPropertyNames(obj));
输出结果如下:
由上可知,Symbol类型的Key不能通过Object.keys()或者for...in来枚举,它未被包含在对象自身的属性名集合中,所以,利用该特性,可以把不对外开放的属性用Symbol定义
2、使用JSON.stringify()将对象转换成JSON字符串,Symbol属性会被排除在外
let obj2 = JSON.stringify(obj) console.log(obj2);//{"age":18,"title":"Engineer"}
3、如何获取Symbol方式定义的对象属性
(1)object的API:Object.getOwnPropertySymbols(obj)
(2)新增的反射API
Object.getOwnPropertySymbols(obj);//[Symbol(name)] Reflect.ownKeys(obj);// ['age', 'title', Symbol(name)]
二、使用Symbol代替常量
我们经常使用常量来代表一种业务逻辑的几种不同的类型,我们希望这些常量是唯一的关系,经常需要为常量赋一个值,常量少的时候还算好,但是常量一多,你可能还得花点脑子好好为他们取个好点的名字。
const TYPE_AUDIO = "AUDIO"; const TYPE_VIDEO = "VIDEO"; const TYPE_IMAGE = "IMAGE"; function handleFileResource(resource) { switch (resource.type) { case TYPE_AUDIO: playAudio(resource); break; case TYPE_VIDEO: playVideo(resource); break; case TYPE_IMAGE: previewImage(resource); break; default: throw new Error("Unknown type of resource"); } }
使用Symbol就更加方便了
const TYPE_AUDIO = Symbol(); const TYPE_VIDEO = Symbol(); const TYPE_IMAGE = Symbol();
这样就可以保证这3个常量是唯一的值了
三、使用Symbol定义类的私有属性/方法
在javaScript中,没有如同java等面向对象语言的定义私有属性的private方法,类上所有定义的属性或者方法都是可以公开访问的。有了Symbol以及模块化机制,类的私有属性和方法变得可能。
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 login["PASSWORD"]; // undefined
由于Symbol常量PASSWORD被定义在a.js模块中,外面模块b.js无法获取此Symbol(Symbol是唯一的),因此PASSWORD只能被限定在a.js中使用,使用它来定义类属性外部模块无法访问,达到了私有化的目的。