Los sÃmbolos son un nuevo valor primitivo introducido por ES6. Su objetivo es proporcionarnos identificadores únicos. En este artÃculo, te indicamos cómo funcionan, de qué manera se utilizan con JavaScript y cómo nos pueden ayudar.
Cómo crear sÃmbolos
Para crear un sÃmbolo nuevo tendremos que utilizar su constructor:
const symbol = Symbol();
La función cuenta con un parámetro string opcional que actúa como descripción.
const symbol = Symbol('description'); console.log(symbol); //Symbol(description)
Lo importante es que, aunque utilices la misma descripción más de una vez, cada sÃmbolo es único.
Symbol('description') === Symbol('description'); //false
Como he dicho antes, los sÃmbolos son valores primitivos nuevos y cuentan con su propio tipo. Podemos comprobarlo utilizando typeof:
typeof Symbol(); //symbol
Convirtiendo a tipo sÃmbolo
Ya sabéis que en Javascript es posible convertir tipos. Una gran parte de esto es la conversión implÃcita que ocurre cuando usamos valores de diferentes tipos juntos:
console.log(1 + " added to " + 2 + " equals " + 3); //1 added to 2 equals 3
Aunque hay tipos que son compatibles, esto no ocurre con los sÃmbolos.
const symbol = Symbol('Hello'); symbol + 'world!'; //Uncaught TypeError: Cannot convert a Symbol value to a string
Si quieres utilizar sÃmbolos de esa manera, tendrás que convertirlo o utilizar la propiedad “description”.
const symbol = Symbol('Hello'); console.log(`${symbol.description} world!`); //Hello world!
Cómo utilizar sÃmbolos
Antes de meternos de lleno con los sÃmbolos, huelga decir que las claves de un objeto solo podÃan ser cadenas. Tratar de usar un objeto como clave para una propiedad no nos devuelve un resultado esperado.
const key = {}; const myObject = { [key]: 'Hello world!' }; console.log(myObject); /* { [object Object]: 'Hello world!' } */
Esto no pasa con los sÃmbolos. La especificación ECMAScript establece que podemos usarlos como claves. Asà que vamos a intentarlo.
const key = Symbol(); const myObject = { [key]: 'Hello world!' }; console.log(myObject); /* { Symbol(): 'Hello world!' } */
Incluso si dos sÃmbolos cuentan con la misma descripción, no se solaparán cuando los utilizamos como claves:
const key = Symbol('key'); const myObject = { [key]: 'Hello world!' }; console.log(myObject[key] === myObject[Symbol('key')]); //false
Esto significa que podemos asignar un número ilimitado de sÃmbolos únicos y no preocuparnos por los conflictos entre ellos.
Accediendo al valor
Ahora, la única forma de acceder a nuestro valor es utilizar el sÃmbolo.
console.log(myObject[key]); // Hello world!
Existen ciertas diferencias cuando se trata de iterar a través de las propiedades de un objeto con sÃmbolos. Las funciones Object.keys, Object.entries y Object.entries no nos dan acceso a ningún valor que use sÃmbolos, lo mismo ocurre con un ciclo for ... in. La forma más sencilla de recorrerlos es usar la función Object.getOwnPropertySymbols.
const key = Symbol(); const myObject = { [key]: 'Hello world!' }; Object.getOwnPropertySymbols(myObject) .forEach((symbol) => { console.log(myObject[symbol]); }); //Hello world!
A juzgar por lo anterior, podemos concluir que los sÃmbolos nos proporcionan una capa oculta debajo del objeto, separado de las claves que son cadenas.
Los sÃmbolos son únicos... al menos, la mayorÃa de las veces
La forma de crear un sÃmbolo global es utilizar la función Symbol.for.
const symbol = Symbol.for('key'); console.log(symbol === Symbol.for('key')); //true
Si tiene dudas acerca sobre si un sÃmbolo es único, puedes usar la función Symbol.keyFor. Devuelve la clave asociada si se encuentra.
Symbol.keyFor( Symbol.for('key') ); //key
Symbol.keyFor( Symbol('key') ); //undefined