Essencialmente, existem dois tipos de valores em JavaScript: primitivos e objetos (que inclui funções). Symbol é um tipo primitivo, único e imutável.
Quando Symbol() é chamado, é garantido que irá retornar um valor único. Poderemos ter o mesmo output, via console.log(), mas será apenas visual, os valores serão considerados distintos.
Também podemos adicionar alguma descrição ao Symbol, que não terá qualquer valor funcional para o código, apenas para o leitor. O que é conveniente para debug, para o desenvolvedor diferenciar os symbols criados.
let symbol1 = Symbol(); let symbol2 = Symbol(); let symbol3 = Symbol('chave'); let symbol4 = Symbol('chave'); console.log(symbol1); // Symbol() console.log(symbol2); // Symbol() console.log(symbol3); // Symbol('chave') console.log(symbol4); // Symbol('chave') console.log(symbol1 == symbol2); //false console.log(symbol3 == symbol4); //false
Ainda, o JavaScript traz nativamente o método "for" para Symbol. Ele irá procurar por symbol existente contendo uma determinada chave, e vai sempre retorná-lo. Caso a chave passada não exista, esta chave será criada (não confundir esta chave com o comentário, anteriormente mencionado).
let symbol5 = Symbol.for('chave'); let symbol6 = Symbol.for('chave'); console.log(symbol5 == symbol6); // true console.log(symbol5 == symbol4 || symbol5 == symbol3); // false
Podemos utilizar o Symbol como chave de uma propriedade de um objeto:
let profissao = Symbol.for('Minha profissão'); let objeto = { nome: 'Pedro Bittencourt' [profissao]: 'Desenvolvedor' }
Tal abordagem não trará grandes seguranças, apenas irá prevenir de erros, ou proteger fracamente algum dado (hoje há alternativas melhores, como o 'Private'#). Há de se acrescentar, ainda, que: quando um Symbol é usado como identificador de uma propriedade esta fica anônima, ou seja são escondidos de loops e funções.
const ganhadoresDaMega = {}; ganhadoresDaMega.concurso01 = 'Maria'; ganhadoresDaMega[Symbol('concurso02')] = 'Jose'; console.log(ganhadoresDaMega) // { concurso01: 'Maria', [Symbol(concurso02)]: 'José'} console.log(Object.keys(ganhadoresDaMega)) // [ 'concurso01' ] for (i in ganhadoresDaMega){ console.log(i); // concurso01 }
Symbols são uteis, realmente, para prevenir erros por se ter nomenclaturas idênticas(colisão de nomes). Imagine uma situação em que será instanciado duas bibliotecas em que irão adicionar algum dado a um objeto e ambas utilizem uma chave 'id' para esta propriedade (o que não é difícil), a chance de colisão é muito grande, vejamos:
function lib1(meuObj) { meuObj.id = 1; } function lib2(meuObj) { meuObj.id = 55; }
Imagine o transtorno que não causaria. Se as bibliotecas utilizassem Symbols, para instanciar a chave da propriedade que elas querem adicionar, evitaria esta colisão:
const lib1Id = Symbol('lib1'); function lib1(meuObj) { meuObj[lib1Id] = 1; } const lib2Id = Symbol('lib2'); function lib2(meuObj) { meuObj[lib2Id] = 55; }
Então, basta lembrar que todo symbol tem um valor único implícito e não pode ser recriado, podendo ser usado como identificador/chave.
Faça parte da nossa comunidade!
Domine as tecnologias utilizadas pelas empresas mais inovadoras do mundo e encare seu novo desafio profissional, evoluindo em comunidade com os melhores experts.