Eae gente bonita, beleza? Continuo a jornada de "aprofundamento" em JavaScript e quanto mais eu aprendo mais eu quero escrever e compartilhar com vocês. Dessa vez vou falar um pouco sobre o Symbol
que para mim o motivo da sua existência sempre foi um mistério.
Tabela de conteúdos
- O que é Symbol
- Criando propriedades "privadas"
- Mas por que "privado"
- Symbols e comportamentos padrão
- Referências
O que é Symbol
Começando do começo, o Symbol é um tipo primitivo no JavaScript, ele é usado para criar valores, funções privadas e até mesmo para interceptar um comportamento padrão de um objeto no JavaScript.
Mas não se esqueça de uma coisa, no JavaScript TUDO é objeto.
Apenas para confirmar que o symbol é um tipo primitivo
typeof Symbol("foo") === "symbol"; // true
Criando propriedades "privadas"
Com o Symbol podemos criar algumas propriedades quase privadas. Abaixo um exemplo
const uniqueKey = Symbol("userName");
const user = {};
user["userName"] = "value normal object";
user[uniqueKey] = "value from symbol";
console.log('getting object', user[uniqueKey]); // "value from symbol"
console.log('getting object', user["userName"]); // "value normal object"
console.log('getting object', user[Symbol("userName")]); // undefined
No exemplo nós criamos a uniqueKey
com o Symbol
com o valor userName
e um objeto user
. Primeiro colocamos um valor na propriedade user["userName"]
e depois fazemos a mesma coisa com a propriedade user[uniqueKey]
e você pode pensar, bom o symbol tem o mesmo valor que é userName, então o valor foi sobrescrito mas na verdade não. O Symbol cria um outro endereço de memória e uma propriedade diferente.
Ok, então se eu criar um Symbol com o mesmo valor eu consigo acessar? Errado novamente. Como disse o Symbol cria um novo endereço na memória logo o terceiro console log retorna undefined. Por isso que com ele nós podemos criar variáves e métodos privados, pois os mesmos só serão acessados se o Symbol usado for exportado junto.
Mas por que "privado"
Bom imagino que deve ter percebido o uso excessivo das aspas em privado isso acontece porque nós podemos saber quais são o symbols existentes. Vamos a mais um exemplo:
const uniqueKey = Symbol("userName");
const func = Symbol("soma");
const user = {};
user[uniqueKey] = "value from symbol";
user[func] = (n1, n2) => n1+ n2;
console.log('symbols', Object.getOwnPropertySymbols(user));// symbols [ Symbol(userName), Symbol(soma) ]
Como podemos ver no exemplo acima os Symbols desse objeto não são privados. Com um simples método do Object
nós podemos ver o Symbols existentes, porém não podemos acessá-los ou ler suas implementações.
Symbols e comportamentos padrão
Com o Symbol nós podemos alterar alguns comportamentos padrão dos objetos, como por exemplo como um objeto será lido por uma função de iterator ou convertido para string.
Vamos aos exemplos!
const obj = {
items: ['c', 'b', 'a'],
}
Para podermos ler o objeto acima em um iterator(for, forEach, map) nós precisariamos usar alguma função como Objeto.entries ou Object.keys para transformar as chaves em um array e ler propriedade por propriedade.
Mas e se quiséssemos que esse objeto fosse lido de forma correta por um iterator? Bom nós podemos mudar esse comportamento, como no exemplo abaixo
const obj = {
[Symbol.iterator]: () => ({
items: ['c', 'b', 'a'],
next() {
return {
done: this.items.length === 0,
value: this.items.pop()
}
}
})
}
Dessa forma podemos apenas chamar uma função de iterator e o nosso objeto será lido sem problema algum. O mesmo vale para toString
por exemplo e por ai vai. Caso queira saber recomendo pesquisar sobre prototypes no JavaScript.
Referências
Espero que tenha sido claro e tenha ajudado a entender um pouco mais sobre o assunto, fique a vontade para dúvidas e sugestões abaixo!
Se chegou até aqui, me segue la nas redes vizinhas.
Top comments (0)