一、Symbol介绍
ES6 引入的一种新的原始数据类型Symbol,表示独一无二的值。Symbol函数可以接受参数,表示对于这个唯一值的描述。
let s = Symbol()
typeof s ; //’symbol’
变量s表示独一无二的值;
实例:
let sy1 = Symbol('sy1');
let sy2 = Symbol('sy2');
console.log(sy1, sy2);
console.log(sy1 == sy2);
结果:
二、方法
1.Symbol.for()
通过该方法可以获取之前的唯一值,它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。
实例:
// .for会到全局注册表中查找,是否有'sy3'这个key值,
// 如果有,将该key值对应的symbol值返回,
// 如果没有,新建一个symbol值
let sy3 = Symbol.for('hello');
let sy4 = Symbol.for('sy3');
console.log(sy3, sy4);
console.log(sy3 == sy4);
结果:
2.Symbol.keyFor()
该方法 返回一个已登记的 Symbol 类型值的 key ,用来检测该字符串参数作为名称的 Symbol 值是否已被登记。
实例:
// .keyFor
let key = Symbol.keyFor(sy3);
console.log(key);
结果:
三、应用
1.作为属性名
由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。
let sy = Symbol("key1");
// 写法1
let syObject = {};
syObject[sy] = "kk";
console.log(syObject); // {Symbol(key1): "kk"}
// 写法2
let syObject = {
[sy]: "kk"
};
console.log(syObject); // {Symbol(key1): "kk"}
// 写法3
let syObject = {};
Object.defineProperty(syObject, sy, {value: "kk"});
console.log(syObject); // {Symbol(key1): "kk"}
Symbol 作为对象属性名时不能用.运算符,要用方括号。因为.运算符后面是字符串,所以取到的是字符串 sy 属性,而不是 Symbol 值 sy 属性。
注意: Symbol 值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问。但是不会出现在 for...in 、 for...of 的循环中,也不会被 Object.keys() 、 Object.getOwnPropertyNames() 返回。如果要读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols() 和 Reflect.ownKeys() 取到。
2.定义常量
const COLOR_RED = Symbol("red");
const COLOR_YELLOW = Symbol("yellow");
const COLOR_BLUE = Symbol("blue");
function ColorException(message) {
this.message = message;
this.name = "ColorException";
}
function getConstantName(color) {
switch (color) {
case COLOR_RED :
return "COLOR_RED";
case COLOR_YELLOW :
return "COLOR_YELLOW ";
case COLOR_BLUE:
return "COLOR_BLUE";
default:
throw new ColorException("Can't find this color");
}
}
try {
var color = "green"; // green 引发异常
var colorName = getConstantName(color);
} catch (e) {
var colorName = "unknown";
console.log(e.message, e.name); // 传递异常对象到错误处理
四、魔术字符串
魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。风格良好的代码,应该尽量消除魔术字符串,改由含义清晰的变量代替。
function getMonth(month){
if(month == "May"){
return true
}else{
return false
}
}
getMonth("May")
比如上文的“May”就是魔术字符串 多次出现,假设要更改这个字符串,需要更改多个地方,如果出现的次数足够多,就会很麻烦,可能会有遗漏导致代码出错,所以应该换用变量来代替它。
const mayMonth = "May"
function getMonth(month){
if(month == mayMonth){
return true
}else{
return false
}
}
getMonth(mayMonth)
let obj = {
attr1: Symbol(),
attr2: Symbol(),
attr3: Symbol(),
}
function myFun (param) {
switch (param) {
case obj.attr1:
console.log(1);
break;
case obj.attr2:
console.log(2);
break;
case obj.attr3:
console.log(3);
break;
default:
console.log(0);
break;
}
}
myFun(obj.attr1);