Símbolo

Browser Support

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

Source

Uma primitiva de símbolo representa um valor exclusivo que nunca colide com nenhum outro valor, incluindo o valor de outras primitivas de símbolo. Duas primitivas de string compostas de caracteres idênticos são avaliadas como estritamente iguais:

String() === String()
> true

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

No entanto, nenhum símbolo criado usando a função Symbol() pode ser estritamente igual:

Symbol() === Symbol()
> false

Essa característica permite usar símbolos como chaves de propriedade exclusivas em um objeto, evitando colisões com chaves que qualquer outro código possa adicionar a esse objeto.

const mySymbol = Symbol( "Desc" );

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

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

Há três tipos de símbolos:

  • Símbolos criados com Symbol()
  • Símbolos compartilhados que são definidos e recuperados de um registro de símbolos global usando Symbol.for()
  • "Símbolos conhecidos" definidos como propriedades estáticas no objeto Symbol. Esses símbolos contêm métodos internos que não podem ser substituídos acidentalmente.

Symbol() aceita uma descrição (ou "nome do símbolo") como um argumento opcional. Essas descrições são rótulos legíveis por humanos para fins de depuração e não afetam a exclusividade do resultado. Qualquer chamada para Symbol retorna uma primitiva de símbolo completamente exclusiva, mesmo que várias chamadas tenham descrições idênticas:

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

Assim como outros tipos de dados primitivos, os símbolos herdam métodos e propriedades do protótipo. Por exemplo, é possível acessar uma descrição como uma propriedade herdada do símbolo criado:

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

mySymbol.description
> "My symbol."

Mas não é possível criar um símbolo usando a palavra-chave new:

let mySymbol = new Symbol();

> Uncaught TypeError: Symbol is not a constructor

Os símbolos não são enumeráveis, ou seja, as propriedades simbólicas não estão disponíveis ao usar métodos padrão para iterar sobre elas. O método getOwnPropertySymbols() dá acesso às propriedades de símbolo de um objeto.

Símbolos compartilhados

O método Symbol.for() tenta procurar todos os símbolos em um registro de símbolos global em tempo de execução com uma string específica como chave e retorna o símbolo correspondente, se encontrado. Se ele não encontrar um, ele vai criar um símbolo com a chave especificada e adicioná-lo ao registro global:

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

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

Essas chaves não têm sobreposição funcional com as descrições atribuídas às primitivas Symbol criadas pelo autor. Para acessar um símbolo no registro de símbolos, primeiro crie-o usando for():

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

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

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

Para recuperar a chave de qualquer símbolo do registro de símbolos, use Symbol.keyFor():

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

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

Símbolos "conhecidos"

Os símbolos conhecidos são propriedades estáticas do objeto Symbol, e cada um deles é um símbolo. Símbolos conhecidos fornecem chaves de propriedade exclusivas para acessar e modificar os métodos integrados do JavaScript, evitando que o comportamento principal seja substituído acidentalmente.

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 ()

Como os símbolos são um recurso específico do ES6, esses valores simbólicos são usados como "pontos de extensão" para que os desenvolvedores modifiquem o comportamento do JavaScript sem introduzir problemas de compatibilidade com versões anteriores.

Os valores de símbolos conhecidos geralmente são estilizados com um prefixo @@ ou envoltos em % para diferenciar as chaves dos protótipos mutáveis. Por exemplo, @@match (ou %match%) é uma referência ao Symbol.match imutável, não String.prototype.match.

Teste seu conhecimento

É possível usar new para criar um símbolo?

Não
Sim

Qual das opções a seguir descreve símbolos "conhecidos"?

Propriedades estáticas do objeto "Symbol"
Símbolos que você usa com frequência
Chaves de propriedade exclusivas para acessar e modificar os métodos integrados do JavaScript