Símbolo

Browser Support

  • Chrome: 38.
  • Edge: 12.
  • Firefox: 36.
  • Safari: 9.

Source

Una primitiva de símbolo representa un valor único que nunca choca con ningún otro valor, incluido el valor de otras primitivas de símbolo. Dos primitivas de cadenas que se componen de caracteres idénticos se evalúan como estrictamente iguales:

String() === String()
> true

String( "My string." ) === String( "My string." );
> true

Sin embargo, no hay dos símbolos creados con la función Symbol() que puedan ser estrictamente iguales:

Symbol() === Symbol()
> false

Esta característica te permite usar símbolos como claves de propiedades únicas en un objeto, lo que evita colisiones con claves que cualquier otro código podría agregar a ese objeto.

const mySymbol = Symbol( "Desc" );

const myObject = {};
myObject[mySymbol] = "propSymbol";

myObject
> Object { Symbol("Desc"): "propSymbol" }

Existen tres tipos de símbolos:

  • Símbolos creados con Symbol()
  • Símbolos compartidos que se establecen y recuperan desde un registro de símbolos global con Symbol.for()
  • "Símbolos conocidos" definidos como propiedades estáticas en el objeto Symbol. Estos símbolos contienen métodos internos que no se pueden reemplazar accidentalmente.

Symbol() acepta una descripción (o "nombre del símbolo") como argumento opcional. Estas descripciones son etiquetas legibles por humanos para depurar y no afectan la unicidad del resultado. Cualquier llamada a Symbol muestra una primitiva de símbolo completamente única, incluso si varias llamadas tienen descripciones idénticas:

Symbol( "My symbol." ) === Symbol( "My symbol." );
> false

Al igual que con otros tipos de datos primitivos, los símbolos heredan métodos y propiedades de su prototipo. Por ejemplo, puedes acceder a una descripción como una propiedad heredada del símbolo creado:

let mySymbol = Symbol( "My symbol." );

mySymbol.description
> "My symbol."

Sin embargo, no puedes crear un símbolo con la palabra clave new:

let mySymbol = new Symbol();

> Uncaught TypeError: Symbol is not a constructor

Los símbolos no son enumerables, lo que significa que las propiedades simbólicas no están disponibles cuando se usan métodos estándar para iterar sobre ellas. El método getOwnPropertySymbols() brinda acceso a las propiedades de símbolo de un objeto.

Símbolos compartidos

El método Symbol.for() intenta buscar cualquier símbolo existente en un registro de símbolos global en todo el entorno de ejecución con una cadena determinada como clave y muestra el símbolo coincidente si se encuentra uno. Si no encuentra uno, crea un símbolo con la clave especificada y la agrega al registro global:

let sharedSymbol = Symbol.for( "My key." );

sharedSymbol === Symbol.for( "My key." )
> true

Estas claves no comparten superposición funcional con las descripciones asignadas a las primitivas Symbol creadas por el autor. Para acceder a un símbolo en el registro de símbolos, primero debes crearlo con for():

Symbol( "String" ) === Symbol( "String" );
> false

Symbol( "String" ) === Symbol.for( "String" );
> false

Symbol.for( "String" ) === Symbol.for( "String" );
> true

Para recuperar la clave de cualquier símbolo del registro de símbolos, usa Symbol.keyFor():

let mySymbol = Symbol.for( "Key." );

Symbol.keyFor( mySymbol ) ;
> "Key."

Símbolos "conocidos"

Los símbolos conocidos son propiedades estáticas del objeto Symbol, cada una de las cuales es un símbolo. Los símbolos conocidos proporcionan claves de propiedad únicas para acceder a los métodos integrados de JavaScript y modificarlos, al tiempo que evitan que se reemplace el comportamiento principal de forma no intencional.

Symbol;
> function Symbol()
    asyncIterator: Symbol(Symbol.asyncIterator)
    for: function for()
    hasInstance: Symbol("Symbol.hasInstance")
    isConcatSpreadable: Symbol("Symbol.isConcatSpreadable")
    iterator: Symbol(Symbol.iterator)
    keyFor: function keyFor()
    length: 0
    match: Symbol("Symbol.match")
    matchAll: Symbol("Symbol.matchAll")
    name: "Symbol"
    prototype: 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")
    <prototype>: function ()

Debido a que los símbolos son una función específica de ES6, estos valores simbólicos están destinados a usarse como "puntos de extensión" para que los desarrolladores modifiquen el comportamiento de JavaScript sin introducir problemas de retrocompatibilidad.

Los valores de símbolos conocidos suelen estilizarse con un prefijo @@ o unirse en % para diferenciar sus claves de sus prototipos mutables. Por ejemplo, @@match (o %match%) es una referencia al Symbol.match inmutable, no a String.prototype.match.

Verifica tu comprensión

¿Puedes usar new para crear un símbolo?

No

¿Cuál de las siguientes opciones describe símbolos “conocidos”?

Propiedades estáticas del objeto "Symbol"
Claves de propiedades únicas para acceder a los métodos integrados de JavaScript y modificarlos
Símbolos que usas con frecuencia