一、使用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中使用,使用它来定义类属性外部模块无法访问,达到了私有化的目的。