概览

const mySymbol = Symbol('mySymbol');console.log(mySymbol); // Symbol(mySymbol)console.log(mySymbol === Symbol('mySymbol')); // falseconsole.log(typeof mySymbol); // 'symbol'

根本数据类型Symbol

ES6 六种根本数据类型: StringNumberBooleanNullUndefinedSymbol
ES6 七种数据类型:StringNumberBooleanNullUndefinedObjectSymbol

类型转换

  • 转字符串(不反对强制转换成字符串)

    // 转Stringconsole.log(mySymbol.toString()); // 'Symbol(mySymbol)'console.log(String(mySymbol)); // 'Symbol(mySymbol)'// console.log(mySymbol + ''); // Cannot convert a Symbol value to a string// console.log(`${mySymbol}`); // Cannot convert a Symbol value to a string
  • 转Boolean

    // 转Boolean  console.log(Boolean(mySymbol)); // trueconsole.log(!mySymbol); // falseif(mySymbol){  console.log(123); // 123}
  • 转Number(不反对)

    // console.log(Number(mySymbol)); //Uncaught TypeError: Cannot convert a Symbol value to a number// console.log(+mySymbol); //Uncaught TypeError: Cannot convert a Symbol value to a number// console.log(1+mySymbol); //Uncaught TypeError: Cannot convert a Symbol value to a number

自定义Symbol属性键

  • 第一种办法

    let ourSymbol = Symbol();let a = {};a[ourSymbol] = 'hello'; console.log(a); // {Symbol(): "hello"}
  • 第二种办法

    let ourSymbol = Symbol();let b = {  [ourSymbol]: 'world'};console.log(b); // {Symbol(): "world"}
  • 第三种办法

    let ourSymbol = Symbol();let c = {};Object.defineProperty(c,ourSymbol,{value: '!'});console.log(c); // {Symbol(): "!"}

留神:不反对点运算符

let ourSymbol = Symbol();a.ourSymbol = '点运算符';console.log(a[ourSymbol]); // undefinedconsole.log(a['ourSymbol']); // '点运算符'

留神:在对象外部,应用Symbol值定义属性时,Symbol值必须放在方括号中。

let s = Symbol();let objNew = {  [s]:function(arg){    console.log(arg);  }};let objNew1 = {  [s](arg){    console.log(arg);  }};objNew[s](123)objNew1[s](234)

Symbol作为属性键

const MY_KEY = Symbol();const MY = Symbol();const FOO = Symbol();const objkEY = {  [MY]:333,  [FOO](fo){    return fo  }};objkEY[MY_KEY] = 123;console.log(objkEY[MY_KEY]); // 123console.log(objkEY[MY]); // 333console.log(objkEY[FOO](11)); // 11

枚举属性键

const keyObj = {  [Symbol('my_key')]: 1,  enum: 2,  nonEnum: 3}Object.defineProperty(keyObj, 'nonEnum', {enumerable: false});console.log(keyObj); // {enum: 2, nonEnum: 3, Symbol(my_key): 1}console.log(Object.getOwnPropertyNames(keyObj)); // 疏忽Symbol属性键:["enum", "nonEnum"]console.log(Object.getOwnPropertySymbols(keyObj)); // 疏忽字符串属性键:[Symbol(my_key)]console.log(Reflect.ownKeys(keyObj)); // 遍历所有属性键:["enum", "nonEnum", Symbol(my_key)]console.log(Object.keys(keyObj)); // 遍历可枚举字符串属性键:["enum"]

Symbol用来示意概念

用于定义一种常量,保障这组常量不相等

let levels = {  DEBUG:Symbol('debug'),  INFO:Symbol('info'),  WARN:Symbol('warn')}console.log(levels.DEBUG, 'debug message');console.log(levels.INFO, 'info message');

其余任何值都不能有雷同的值————保障switch语句设计的形式工作

const COLOR_RED = Symbol();const COLOR_GREEN = Symbol();function getComplement(color) {  switch(color) {    case COLOR_RED:      return COLOR_GREEN;    case COLOR_GREEN:      return COLOR_RED;    default:       throw new Error('undefined')  }}console.log(getComplement(COLOR_RED));console.log(getComplement(COLOR_GREEN));// console.log(getComplement('21321'));

Symbol的办法和属性

console.dir(Symbol);// ƒ Symbol()// arguments: (...)// asyncIterator: Symbol(Symbol.asyncIterator)// caller: (...)// for: ƒ for()// hasInstance: Symbol(Symbol.hasInstance)// isConcatSpreadable: Symbol(Symbol.isConcatSpreadable)// iterator: Symbol(Symbol.iterator)// keyFor: ƒ keyFor()// length: 0// match: Symbol(Symbol.match)// matchAll: Symbol(Symbol.matchAll)// name: "Symbol"// prototype: Symbol {constructor: ƒ Symbol()//     description: (...)//     toString: ƒ toString()//     valueOf: ƒ valueOf()//     Symbol(Symbol.toPrimitive): ƒ [Symbol.toPrimitive]()//     Symbol(Symbol.toStringTag): "Symbol"//     get description: ƒ description()//     __proto__: Object// }// replace: Symbol(Symbol.replace)// search: Symbol(Symbol.search)// species: Symbol(Symbol.species)// split: Symbol(Symbol.split)// toPrimitive: Symbol(Symbol.toPrimitive)// toStringTag: Symbol(Symbol.toStringTag)// unscopables: Symbol(Symbol.unscopables)
Symbol.for() 承受一个字符串作参数,而后搜寻有没有以该参数作为名称的Symbol值。如果有就返回Symbol值,否则返回一个以该字符串为名称的Symbol值
Symbol.keyFor() 返回一个已登记的Symbol类型值的key
const s1 = Symbol.for('foo');const s2 = Symbol.for('foo');const s3 = Symbol('foo');const s4 = Symbol('foo');console.log(s1 === s2); // trueconsole.log(s3 === s4); // falseconsole.log(Symbol.keyFor(s1)); // 'foo'console.log(Symbol.keyFor(s2)); // 'foo'console.log(Symbol.keyFor(s3)); // undefinedconsole.log(Symbol.keyFor(s4)); // undefined
Symbol.prototype.toString() 办法返回以后 symbol 对象的字符串示意。
Symbol.prototype.valueOf() 办法返回以后 symbol 对象所蕴含的 symbol 原始值。
// console.log(Symbol('foo') + 'bar'); // Uncaught TypeError: Cannot convert a Symbol value to a stringconsole.log(Symbol('foo').toString() + 'bar'); // Symbol(foo)barconsole.log(Object(Symbol('foo')).toString() + 'bar'); // Symbol(foo)barSymbol("desc").toString();   // "Symbol(desc)"// well-known symbolsSymbol.iterator.toString();  // "Symbol(Symbol.iterator)// global symbolsSymbol.for("foo").toString() // "Symbol(foo)"// Object(Symbol("foo")) + "bar";// TypeError: can't convert symbol object to primitive// 无奈隐式的调用 valueOf() 办法console.log(Object(Symbol("foo")).valueOf()); // Symbol(foo)console.log(Symbol("foo").valueOf()); // Symbol(foo)// console.log(Object(Symbol("foo")).valueOf() + "bar");// TypeError:  can't convert symbol to string// 手动调用 valueOf() 办法,尽管转换成了原始值,但 symbol 原始值不能转换为字符串console.log(Object(Symbol("foo")).toString() + "bar");// "Symbol(foo)bar",须要手动调用 toString() 办法才行

Symbol.asyncIterator 符号指定了一个对象的默认异步迭代器。如果一个对象设置了这个属性,它就是异步可迭代对象,可用于for await...of循环。

Symbol.hasInstance用于判断某对象是否为某结构器的实例。因而你能够用它自定义instanceof操作符在某个类上的行为。

Symbol.isConcatSpreadable符号等于一个布尔值;用于配置某对象作为Array.prototype.concat()办法的参数时是否开展其数组元素。

Symbol.iterator为每一个对象定义了默认的迭代器。该迭代器能够被for...of循环应用。

Symbol.match指定了匹配的是正则表达式而不是字符串。

Symbol.matchAll返回一个迭代器,该迭代器依据字符串生成正则表达式的匹配项。

Symbol.replace这个属性指定了当一个字符串替换所匹配字符串时所调用的办法。

Symbol.search 指定了一个搜寻办法,这个办法承受用户输出的正则表达式,返回该正则表达式在字符串中匹配到的下标。

Symbol.species是个函数值属性,其被构造函数用以创立派生对象。

Symbol.split指向 一个正则表达式的索引处宰割字符串的办法。

Symbol.toPrimitive 是一个内置的 Symbol 值,它是作为对象的函数值属性存在的,当一个对象转换为对应的原始值时,会调用此函数。

Symbol.toStringTag 是一个内置 symbol,它通常作为对象的属性键应用,对应的属性值应该为字符串类型,这个字符串用来示意该对象的自定义类型标签,通常只有内置的 Object.prototype.toString() 办法会去读取这个标签并把它蕴含在本人的返回值里。

Symbol.unscopables 指用于指定对象值,其对象本身和继承的从关联对象的 with 环境绑定中排除的属性名称。

ES6 Symbol