Le Tutoriel de ECMAScript Symbol (ES6)

View more Tutorials:

1- Concept de Symbol

Symbol est un nouveau "type de données primitives" (Primitive data type), introduit en  ECMAScript 6. Avant  ES6 nous avons 5 types primatifs:  Number, String, Boolean, null, undefined.
Afin de créer un Symbol vous pouvez utiliser la syntaxe ci-dessous :
// Create a Symbol
var mySymbol1  = Symbol();

// Create a Symbol
var mySymbol2 = Symbol("Something");
Notez que  Symbol n'est pas une classe donc vous ne pouvez pas le créer par l'opérateur  new :
var mySymbol1 = new Simbol(); // ==> ERROR!!

var mySymbol2 = new Simbol("Something"); // ==> ERROR!!
Tous les types primatifs tels que  Number, String, Boolean, null, undefined sont très clairs et explicites.
  • Number: 1, 2, 3, ...
  • String: "Hello", "Bye", ...
  • Boolean: true, false
  • null
  • undefined
Symbol est une abstraction. Vous ne pouvez ni le toucher ni savoir ce qui est sa valeur réelle. Le Symbol est complètement unique (complètement différent), ce qui signifie que si vous créez deux Symbol, ils sont différents, même si vous créez deux Symbol de la même manière.
symbol-example1.js
var symbolA1 = Symbol();
var symbolA2 = Symbol();

console.log(symbolA1); // Symbol()
console.log(symbolA2); // Symbol()
console.log(symbolA1 === symbolA2); // false

var symbolB1 = Symbol("Tom");
var symbolB2 = Symbol("Tom");

console.log(symbolB1); // Symbol(Tom)
console.log(symbolB2); // Symbol(Tom)
console.log(symbolB1 === symbolB2); // false
 

2- Symbol - Key

Symbol peut être utilisé comme une clé (Key) des objets  Map.
symbol-map-key-example.js
var key1 = Symbol();
var key2 = Symbol();
var key3 = Symbol("Something");

var map = new Map();

map.set(key1, "Tom");
map.set("a_string_key", "Donald");
map.set(key2, "Jerry");
map.set(key3, "Mickey");

console.log( map.get(key1));  // Tom
console.log( map.get("a_string_key")); // Donald
console.log( map.get(key2));  // Jerry
console.log( map.get(key3));  // Mickey
 

[Symbol]?

Symbol peut être utilisé comme une  property d'un objet.
symbol-object-property-example.js
var prop1 = Symbol();
var prop2 = Symbol();
var prop3 = Symbol("Something");

var myObject = {
   name : "Tom",
   gender: "Male",
   [prop1]: "Something 1",
   [prop2]: "Something 2",
   [prop3]: "Something 3",
};

console.log( myObject["name"] );  // Tom
console.log( myObject["gender"] ); // Male

console.log( myObject[prop1] ); // Something 1
Le  Symbol est vraiment utile lors que vous définissez  metadata (métadonnées) dans un objet. Si la  property (d'un objet) est un  Symbol, elle ne sera pas reconnue pas les fonctions qui renvoie des  property.
symbol-metadata-example.js
const sym = Symbol()

const foo = {
  name: 'Tom',
  age: 25,
  [sym]: 'Some Hidden Metadata'
}

let keys = Object.keys(foo) // name, age
console.log("keys: " + keys);

let propNames = Object.getOwnPropertyNames(foo) // name, age
console.log("propNames: " + propNames);

for(let val of keys) {
  console.log(foo[val]) // Tom // 25
}
Les  Symbol Property ne sont pas complètement cachés. Vous pouvez encore faire une liste des  Symbol Property d'un objet via les méthodes ci-dessous :
Object.getOwnPropertySymbols(someObject);

Reflect.ownKeys(someObject);
 
Exemple :
symbol-get-props-example.js
const sym1 = Symbol();
const sym2 = Symbol("Test");

const someObject = {
  name: 'Tom',
  age: 25,
  [sym1]: 'Some Hidden Metadata 1',
  [sym2]: 'Some Hidden Metadata 2'
}

var symbolProps = Object.getOwnPropertySymbols(someObject);

console.log(symbolProps); // [ Symbol(), Symbol(Test) ]

var objKeys = Reflect.ownKeys(someObject);

console.log(objKeys); // [ 'name', 'age', Symbol(), Symbol(Test) ]
 

3- Symbol - Enums

En  ES5 vous devez créer des constants fréquemment afin de représenter un concept. Et les données sont normalement utilisées pour définir  un constant est  Number ou  String.
OK, par exemple, vous devez créer quatre constants pour représenter les quatre saisons d'un an, et la fonction  getWeather(season) renvoie le temps qui correspond à la saison transmise.
var SEASON_SPRING = "SPRING";
var SEASON_SUMMER = "SUMMER";
var SEASON_AUTUMN = "AUTUMN";
var SEASON_WINTER = "WINTER";

function getWeather(season)  {
   switch(season) {
      case SEASON_SPRING:
         return "warm";
      case SEASON_SUMMER:
         return "hot";
      case SEASON_AUTUMN:
         return "cool";
      case SEASON_WINTER:
          return "cold";
      default:
         throw 'Invalid season';
   }
}

console.log( getWeather(SEASON_SPRING) ); // warm
Parfois, vous utilisez des constantes incorrectement dans le code mais cela est toujours accepté par le programme. Pourtant, c'est dangereux.
var SEASON_SPRING = "SPRING";
var SEASON_SUMMER = "SUMMER";
var SEASON_AUTUMN = "AUTUMN";
var SEASON_WINTER = "WINTER";

var FRAMEWORK_SPRING = "SPRING";
var FRAMEWORK_STRUTS = "STRUTS";


var weather1 = getWeather( SEASON_SPRING ); // warm

// (***)
var weather2 = getWeather( FRAMEWORK_SPRING ); // warm
L'utilisation de  Symbol pour définir des constants est une bonne solution pour vous dans ce cas. Les constants du type  Symbol qui représentent un concept précis sont nommés  Enums (similaire au concept  Enums en  Java).
symbol-enums-example.js
// Season Enums:
const SEASON_SPRING = Symbol();
const SEASON_SUMMER = Symbol();
const SEASON_AUTUMN = Symbol();
const SEASON_WINTER = Symbol();

// Framework Enums:
const FRAMEWORK_SPRING = Symbol();
const FRAMEWORK_STRUTS = Symbol();

function getWeather(season)  { // Season Enums
   switch(season) {
      case SEASON_SPRING:
         return "warm";
      case SEASON_SUMMER:
         return "hot";
      case SEASON_AUTUMN:
         return "cool";
      case SEASON_WINTER:
          return "cold";
      default:
         throw 'Invalid season';
   }
}

console.log( getWeather(SEASON_SPRING) ); // warm

console.log( getWeather(FRAMEWORK_SPRING) ); // Throw Error: Invalid season

4- Symbol.for(key) & Symbol.forKey(symbol)

La méthode  Symbol.for(keyName) renvoie une valeur comme un  Symbol correspondant à la clé  keyName dans un objet  Map global (Global). Si la clé  keyName n'existe pas dans l'objet  Map global, une paire  keyName/Symbol(keyName) sera ajoutée à l'objet  Map, et renvoie le  Symbol(keyName) mentionné au-desous.
symbol-for-example.js
const tom = Symbol.for('Tom') // If the Symbol does not exist, it's created

const tom2 = Symbol.for('Tom') // The Symbol exists, so it is returned

console.log( tom === tom2); // true
 
Symbol.for() & Symbol.for(undefined) sont les même.
symbol-for-example2.js
const foo = Symbol.for();

const bar = Symbol.for(undefined);

console.log( foo === bar); // true
Si un  Symbol est géré sur l'objet  Map global, vous pouvez trouver sa clé en utilisant la méthode  Symbol.keyFor(symbol).
symbol-keyFor-example.js
const foo = Symbol.for('someKey');// This Symbol in Global Map.

const key1 = Symbol.keyFor(foo); // someKey
console.log(key1); // someKey


const bar = Symbol("Test");// This Symbol not in Global Map.

const key2 = Symbol.keyFor(bar);
console.log(key2); // undefined

View more Tutorials: