This is the 19th day of my participation in the Genwen Challenge

1. An overview of the

Object attribute names in ES5 are all strings, which can easily cause attribute name conflicts. For example, if you use an object provided by someone else and want to add a new method to the object (the mixin pattern), the name of the new method may conflict with the existing method. It would be nice if there were a mechanism to ensure that each property name was unique, preventing property name conflicts at all. This is why ES6 introduced Symbol.

ES6 introduces a new primitive data type, Symbol, that represents unique values. It is the seventh data type in JavaScript, with undefined, NULL, Boolean, String, Number, and Object being the first six.

The Symbol value is generated by the Symbol function. This means that object property names can now be of two types: the original string and the new Symbol type. Attribute names that belong to the Symbol type are unique and are guaranteed not to conflict with other attribute names.

let s = Symbol(a);// New Symbol() is not supported

typeof s
// "symbol"
Copy the code

Note that the parameter to the Symbol function only represents a description of the current Symbol value, so the return value of the Symbol function with the same parameter is not equal.

// No arguments
let s1 = Symbol(a);let s2 = Symbol(a); s1 === s2// false

// With parameters
let s1 = Symbol('foo');
let s2 = Symbol('foo');

s1 === s2 // false
Copy the code

This also reflects the uniqueness of Symbol.

But it’s not impossible to tell if the parameters they pass are equal.

let s1 = Symbol('foo');
let s2 = Symbol('foo');

s1.toString() === s2.toString()  // true
Copy the code

Doing so would violate Symbol’s intent and is not recommended. MDN Description of the parameter passed This parameter is an optional string. A description of a symbol that can be used to debug but not access the symbol itself. So the argument passed in doesn’t mean anything.

2. Symbol as attribute name

Since each Symbol value is not equal, this means that the Symbol value can be used as an identifier for the property name of the object, ensuring that no property with the same name will appear. This is useful in cases where an object is made up of multiple modules, preventing a key from being accidentally overwritten or overwritten.

let mySymbol = Symbol(a);// The first way
let a = {};
a[mySymbol] = 'Hello! ';

// The second way
let a = {
  [mySymbol]: 'Hello! '
};

// The third way
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello! ' });

// All the above methods give the same result
a[mySymbol] // "Hello!"
Copy the code

Inside an object, when defining a property using a Symbol value, the Symbol value must be placed in square brackets.

let s = Symbol(a);let obj = {
  [s]: function (arg) {... }}; obj[s](123);

// enhance the notation
letobj = { [s](arg) { ... }};Copy the code

The Symbol type can also be used to define a set of constants that are guaranteed to have unequal values.

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

// Second example
const COLOR_RED    = Symbol(a);const COLOR_GREEN  = Symbol(a);function getComplement(color) {
  switch (color) {
    case COLOR_RED:
      return COLOR_GREEN;
    case COLOR_GREEN:
      return COLOR_RED;
    default:
      throw new Error('Undefined color'); }}Copy the code

The great advantage of using the Symbol value for constants is that no other value can have the same value, thus ensuring that the switch statement above works as designed.

reference

  • [1] Yifeng Ruan: Introduction to ECMAScript6
  • [2] MDN