Symbol(符号)是 ECMAScript 6 新增的数据类型。符号是原始值,且符号实例是唯一、不可变的。 符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。 符号并不是为了提供私有属性的行为才增加的(尤其是因为 Object API 提供了方法,可以更方便地发现符号属性)。相反,符号就是用来创建唯一记号,进而用作非字符串形式的对象属性。

3.4.7.1 符号的基本用法

符号需要使用 Symbol()函数初始化。因为符号本身是原始类型,所以 typeof 操作符对符号返回 symbol。

  1. let sym = Symbol();
  2. console.log(typeof sym); // symbol
  3. //可以传入一个字符串参数作为对符号的描述,以通过这个字符串来调试代码
  4. //这个字符串参数与符号定义或标识完全无关
  5. let genericSymbol = Symbol();
  6. let otherGenericSymbol = Symbol();
  7. let fooSymbol = Symbol('foo');
  8. let otherFooSymbol = Symbol('foo');
  9. console.log(genericSymbol == otherGenericSymbol); // false

符号没有字面量语法,按照规范,你只要创建 Symbol()实例并将其 用作对象的新属性,就可以保证它不会覆盖已有的对象属性,无论是符号属性还是字符串属性

  1. let genericSymbol = Symbol();
  2. console.log(genericSymbol); // Symbol()
  3. let fooSymbol = Symbol('foo');
  4. console.log(fooSymbol); // Symbol(foo);

Symbol()函数不能与 new 关键字一起作为构造函数使用。这样做是为了避免创建符 号包装对象,像使用 Boolean、String 或 Number 那样,它们都支持构造函数且可用于初始化包含原 始值的包装对象:

  1. let myBoolean = new Boolean();
  2. console.log(typeof myBoolean); // "object"
  3. let myString = new String();
  4. console.log(typeof myString); // "object"
  5. let myNumber = new Number();
  6. console.log(typeof myNumber); // "object"
  7. let mySymbol = new Symbol(); // TypeError: Symbol is not a constructor
  8. 如果你确实想使用符号包装对象,可以借用 Object()函数:
  9. let mySymbol = Symbol();
  10. let myWrappedSymbol = Object(mySymbol);
  11. console.log(typeof myWrappedSymbol); // "object"