什么是 Symbol
Symbol 是 ES6 中引入的一种新的基本数据类型,用于表示一个独一无二的值。它是 JavaScript 中的第七种数据类型,与 undefined、null、Number、String、Boolean、Object 并列
创建一个 Symbol 值的方式如下:
const a = Symbol();
console.log(a); // Symbol()
console.log(typeof a) // 类型是:Symbol
Symbol 的语法规范
- 基本语法
上面介绍到,使用如下语法可创建一个 Symbol 变量
let a = Symbol();
使用上述语句创建的变量 a,在控制台中进行输出时会显示为 Symbol。加入还有另一个变量
let a = Symbol();
let b = Symbol();
console.log(a); // Symbol()
console.log(b); // Symbol()
console.log(a === b); // false
由 a === b 返回的结果为 false 可知 Symbol 值是唯一的,变量 a 和变量 b 并不是同一个值,但他们在控制台的输出却是一样的。
这样不利于我们区分两个变量,为此,我们可以在调用 Symbol 的时候传入一个字符串作为对当前 Symbol 变量的描述:
let a = Symbol("symbol1");
let b = Symbol("symbol2");
console.log(a); // Symbol(symbol1)
console.log(b); // Symbol(symbol2)
现在我们可以在控制台中区分开变量 a 和变量 b 了。
注意: Symbol 是基本数据类型,调用 Symbol 时不可以使用 new 关键字。
-
Symbol 属性的遍历
以 Symbol 类型的变量作为对象属性时,该属性不会出现在 for…in、for…of 循环中 -
Symbol.for(),Symbol.keyFor()
(1) Symbol.for():Symbol 提供的一种可以创建相同 Symbol 的机制,就是使用 Symbol.for() 传入相同的描述符时,就可以得到相同的 Symbol 值,所以变量 a 和 b 是相同的,比较后返回结果为 true。
let a = Symbol.for('imooc'); // 全局注册了以“imooc”为描述符的 Symbol
let b = Symbol.for('imooc'); // 由于描述符“imooc”已被注册到全局,因此这里创建的 Symbol 与上面是同一个
console.log(a === b); // true
(2) Symbol.keyFor(): 返回一个全局注册的 Symbol 的描述符
let a = Symbol.for('imooc');
let res = Symbol.keyFor(a);
console.log(res); // imooc
返回结果是已经注册过的变量 a 的描述符 imooc。
Symbol 的作用
由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性,这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。
let s1 = Symbol();
let s2 = Symbol();
const obj = {
age: 16,
age: 19,
[s1]: 'Hello!',
[s2]: 'world'
}
console.log(obj);
由于 age 是字符串类型的,同名属性会被覆盖,所以 obj 对象中只会有一个 age 属性,而 Symbol 值是唯一的,即使控制台中输出结果看起来是一样的,但他们并不表示同一个值,所以 obj 中 s1 和 s2 都可以添加到 obj 对象中。
为了方便区分,可以给 Symbol 值添加描述
let s1 = Symbol('s1');
let s2 = Symbol('s2');
const obj = {
age: 16,
age: 19,
[s1]: 'Hello!',
[s2]: 'world'
}
console.log(obj);
obj 中添加了两个 Symbol 值作为属性名,描述分别为 s1、s2
常用内置的 Symbol 值:Symbol.iterator
对象的 Symbol.iterator 属性,指向该对象的默认遍历器方法,凡是具有[Symbol.iterator] 方法的对象都是可遍历的,可以使用 for…of 循环依次输出对象的每个属性
数组和类数组,以及 ES6 新增的 Map、Set 等都原生部署了该方法,因此它们都可遍历
Symbol 与基本数据类型转换
(1) Symbol 不能转成数字。
使用 Number 对 Symbol 值转换会出现报错
let s1 = Symbol('1');
console.log(Number(s1));
(2) 可以转换成布尔值和字符串
let s1 = Symbol('1');
console.log(typeof s1); // symbol
let str = String(s1);
console.log(typeof str); // string
let bool = Boolean(s1);
console.log(typeof bool); //boolean
Symbol 值可以通过 String 转成字符串形式,通过 Boolean 转成布尔值
总结
一般 Symbol 值就是为对象属性的键值,防止该属性被覆盖,使用 Symbol 作为对象属性时,需要使用方括号语法去访问对应的属性,而不是字符串。