什么是Symbol
Symbol为符号类型,属于基本数据类型之一。
Symbol() 可以用来生成唯一值。在之前,对象以字符串的形式存在,所以极易引发键名冲突问题,而Symbol的出现正是解决了这一痛点。
Symbol的使用
1、创建Symbol:
let a = Symbol();
console.log(typeof a); //symbol
2、需注意不能使用new来搭配Symbol() 构造实例,会抛出错误:
let a = new Symbol();
console.log(typeof a); //Symbol is not a constructor
如果想得到一个Symbol() 的对象形式,可以使用Object()函数:
let a = Symbol();
let b = Object(a);
console.log(typeof b); //object
3、在调用Symbol函数时可以传递一个字符串参数用来区分:
let a = Symbol("a");
let b = Symbol("b");
Symbol的应用
1、作为对象的属性
如果我们在不了解一个对象的时候,想为其添加一个方法或者属性,又怕键名重复引起覆盖的问题,这个时候我们就需要一个唯一性的键来解决这个问题,于是就有了Symbol,它可以作为对象的属性的键,避免冲突:
let a = Symbol();
let obj = {};
obj[a] = "nigel";
这里需注意的是我们无法使用 . 来调用对象的Symbol属性,所以必须使用 [ ] 来访问Symbol的属性。
2、降低代码耦合
我们经常会遇到与代码强耦合的字符串,可以理解为:与代码强制绑定在一起,然而这会导致一个问题,在条件判断复杂的情况下,我们需要更改每一个判断控制,维护起来非常麻烦,所以我们可以声明一个存储判断条件字符串的对象,通过修改对象来自如地控制判断条件。利用Symbol的特性,可以使我们的条件判断更加精确。为了更直观地了解优化过程,下面创建一个求面积的工具函数:
const judge = {
rectangle: Symbol("rectangle"),
triangle: Symbol("triangle"),
};
function getArea(model, size) {
switch (model) {
case judge.rectangle:
return size.width * size.height;
case judge.triangle:
return (size.width * size.height) / 2;
}
}
let area = getArea(judge.rectangle, { width: 100, height: 200 });
console.log(area);
3、全局共享Symbol
我们想在不同的地方调用同一Symbol即全局共享的Symbol,可以通过Symbol.for() 方法,参数为创建时传入的描述字符串,该方法可以遍历全局注册表中的Symbol,当搜素到相同描述,那么会调用这个Symbol,如果没有搜索到,就会创建一个新的Symbol:
let a = Symbol.for("a");
let b = Symbol.for("a");
console.log(a === b); //true
需要注意使用Symbol("a") 直接创建的Symbol不在全局注册表中,所以与Symbol.for("a") 创建的Symbol不同:
let a = Symbol("a");
let b = Symbol.for("a");
console.log(a === b); //false
Symbol.keyfor() 可以通过变量名查询该变量名对应的Symbol是否在全局注册表中,如果查询存在则返回该Symbol的描述,不存在则返回undefined:
let a = Symbol("a");
let b = Symbol.for("a");
console.log(Symbol.keyFor(a)); //undefined
console.log(Symbol.keyFor(b)); //'a'
以上就是ES6中Symbol的基本使用及特性