Tipo de dato Symbol en JavaScript
En ECMAScript 6 se agrego un nuevo tipo de dato llamado Symbol. Los simbolos son valores primitivos, inmutables y cada instancia es única.
El proposito de este tipo de dato es garantizar identificadores únicos para las propiedades de los objetos, y de esta manera no tener el riesgo de colisión de propiedades.
Uso
Los simbolos son instanciados usando la función Symbol(). Si usamos el operador typeof con un símbolo entonces nos retornará symbol.
const symbolExample = Symbol();
console.log(typeof symbolExample); // symbol
Cuando invocamos la función Symbol, podemos pasarle una cadena que será usada para identificar la instancia del símbolo. Pero igual debemos de tomar en cuenta por mas que le pasemos la misma cadena a la función, al final cada instancia será diferente.
const symbolOne = Symbol();
const symbolTwo = Symbol();
console.log(symbolOne === symbolTwo); // false
const nameSymbol = Symbol('name');
const otherNameSymbol = Symbol('name');
console.log(nameSymbol === otherNameSymbol); // false
Es importante destacar que la función Symbol no se puede utilizar con la keyword new. El proposito de esto es para evitar symbol object wrappers, como es posible con Boolean, String, y Number que admiten el comportamiento de constructor y crean una instancia de un primitive wrapper object.
const anyBoolean = new Boolean();
console.log(typeof anyBoolean); // object
const anyString = new String();
console.log(typeof anyString); // object
const anyNumber = new Number();
console.log(typeof anyNumber); // object
const anySymbol = new Symbol(); // TypeError: Symbol is not a constructor
Usando el Registro Global de Simbolos
En escenarios en donde diferentes partes del runtime podrian querer compartir o reusar una instancia de symbol, es posible crear y reusar simbolos usando una cadena como clave del registro global de simbolos.
Symbol.for()
Esto puede ser logrado usando Symbol.for().
const ageGlobalSymbol = Symbol.for('age');
Symbol.for() es una operación idempotente para cada cadena clave. La primera vez es llamada con la cada dada, esto revisará el registro global de simbolos, si no existe ningún símbolo, entonces genera una nueva instancia de símbolo y lo agrega al registro.
Si se invoca nuevamente la función con la misma cadena, entonces revisara el registro global de simbolos y como ya tenemos uno con esa clave, entonces devolverá ese que hemos creado.
const cityGlobalSymbol = Symbol.for('city');
const otherCityGlobalSymbol = Symbol.for('city');
console.log(cityGlobalSymbol === otherCityGlobalSymbol); // true
Los simbolos definidos en el registro global son totalmente distintos de los simbolos creados usando Symbol(), aún si le pasamos la misma cadena.
const localSymbol = Symbol('a');
const globalSymbol = Symbol.for('a');
console.log(localSymbol === globalSymbol); // false
Symbol.keyFor()
Es posible obtener la cadena que le hemos pasado como clave al símbolo global. Para esto usamos la función Symbol.keyFor().
const symbolB = Symbol.for('b');
console.log(Symbol.keyFor(symbolB)); // b
Si no le pasas un símbolo a Symbol.keyFor() entonces te retornará un error.
Symbol.keyFor(666); // TypeError: 666 is not a symbol
Usando simbolos como propiedades
En cualquier lugar donde puedas usar una cadena o número como propiedad, tu tambien puedes usar un símbolo. Esto incluye a propiedades de objetos literales, Object.defineProperty() y Object.defineProperties().
Un objeto literal solo puede usar un símbolo como propiedad dentro de la sintaxis de propiedad calculada.
const p1 = Symbol('abc'),
p2 = Symbol('def'),
p3 = Symbol('ghi'),
p4 = Symbol('jkl'),
p5 = Symbol('mno');
let objectExample = {
[p1]: 'abc',
};
objectExample[p2] = 'def';
Object.defineProperty(objectExample, p3, { value: 'ghi' });
Object.defineProperties(objectExample, {
[p4]: { value: 'jkl' },
[p5]: { value: 'mno' },
});
console.log(objectExample);
// {Symbol(abc): "abc", Symbol(def): "def", Symbol(ghi): "ghi", Symbol(jkl): "jkl", Symbol(mno): "mno"}
Y esto es todo lo básico que podemos aprender sobre el tipo de dato Symbol en JavaScript. En otros artículos puedes leer temas más profuncos sobre este tipo de dato.