Este post é sobre o Symbol()
, fornecido com exemplos reais que eu poderia encontrar / criar e fatos e definições que eu poderia encontrar.
TLDR;
O Symbol()
é o tipo de dados, introduzido com o lançamento do ECMAScript 6 (ES6).
Existem dois fatos curiosos sobre o símbolo.
o primeiro tipo de dados e apenas o tipo de dados em JavaScript que não possui literal
qualquer variável, definida com Symbol()
, obtém conteúdo exclusivo, mas não é realmente privado .
qualquer dado possui seu próprio símbolo e, para os mesmos dados, os símbolos seriam os mesmos . Mais informações no parágrafo a seguir, caso contrário, não é um TLRD; :)
Como inicializo o símbolo?
1. Para obter um identificador exclusivo com um valor depurável
Você pode fazê-lo desta maneira:
var mySymbol1 = Symbol();
Ou assim:
var mySymbol2 = Symbol("some text here");
A "some text here"
cadeia não pode ser extraída do símbolo, é apenas uma descrição para fins de depuração. Não muda o comportamento do símbolo de forma alguma. No entanto, você pode console.log
(o que é justo, já que o valor é para depuração, para não confundir esse log com outra entrada de log):
console.log(mySymbol2);
// Symbol(some text here)
2. Para obter um símbolo para alguns dados de string
Nesse caso, o valor do símbolo é realmente levado em consideração e, dessa forma, dois símbolos podem não ser exclusivos.
var a1 = Symbol.for("test");
var a2 = Symbol.for("test");
console.log(a1 == a2); //true!
Vamos chamar esses símbolos de "segundo tipo". Eles não se cruzam com os símbolos do "primeiro tipo" (isto é, os definidos com Symbol(data)
) de forma alguma.
Os próximos dois parágrafos pertencem apenas ao símbolo do primeiro tipo .
Como me beneficio do uso do Symbol em vez dos tipos de dados mais antigos?
Vamos primeiro considerar um objeto, um tipo de dados padrão. Poderíamos definir alguns pares de valores-chave e ter acesso aos valores especificando a chave.
var persons = {"peter":"pan","jon":"doe"};
console.log(persons.peter);
// pan
E se tivermos duas pessoas com o nome Peter?
Fazendo isso:
var persons = {"peter":"first", "peter":"pan"};
não faria muito sentido.
Portanto, parece ser um problema de duas pessoas absolutamente diferentes com o mesmo nome. Vamos então nos referir a novos Symbol()
. É como uma pessoa na vida real - qualquer pessoa é única , mas seus nomes podem ser iguais. Vamos definir duas "pessoas".
var a = Symbol("peter");
var b = Symbol("peter");
Agora temos duas pessoas diferentes com o mesmo nome. Nossas pessoas são realmente diferentes? Eles são; você pode verificar isso:
console.log(a == b);
// false
Como nos beneficiamos lá?
Podemos fazer duas entradas no seu objeto para as diferentes pessoas e elas não podem ser confundidas de forma alguma.
var firstPerson = Symbol("peter");
var secondPerson = Symbol("peter");
var persons = {[firstPerson]:"first", [secondPerson]:"pan"};
Nota:
Vale a pena notar, no entanto, que a string do objeto JSON.stringify
descartará todos os pares inicializados com um símbolo como chave.
A execução Object.keys
também não retornará esses Symbol()->value
pares.
Usando esta inicialização, é absolutamente impossível confundir as entradas para a primeira e a segunda pessoas. Chamar console.log
por eles produzirá corretamente seus segundos nomes.
console.log(persons[a]);
// first
console.log(persons[b]);
// pan
Quando usado no objeto, como ele é diferente em comparação à definição de propriedade não enumerável?
De fato, já existia uma maneira de definir uma propriedade a ser oculta Object.keys
e enumerada. Aqui está:
var anObject = {};
var fruit = "apple";
Object.defineProperty( anObject, fruit, {
enumerable: false,
value: "green"
});
Que diferença Symbol()
traz para lá? A diferença é que você ainda pode obter a propriedade definida Object.defineProperty
da maneira usual:
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //green
console.log(anObject.apple); //green
E se definido com o símbolo como no parágrafo anterior:
fruit = Symbol("apple");
Você terá a capacidade de receber seu valor somente se conhecer sua variável, ou seja,
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //undefined
console.log(anObject.apple); //undefined
Além disso, definir outra propriedade sob a chave "apple"
fará com que o objeto descarte a mais antiga (e, se for codificado, poderá gerar um erro). Então, não há mais maçãs! É uma pena. Referindo-se ao parágrafo anterior, os Símbolos são únicos e definem uma chave, o Symbol()
que a tornará única.
Conversão e verificação de tipo
Ao contrário de outros tipos de dados, é impossível convertê-lo Symbol()
em qualquer outro tipo de dados.
É possível "criar" um símbolo com base no tipo de dados primitivo chamando Symbol(data)
.
Em termos de verificação do tipo, nada muda.
function isSymbol ( variable ) {
return typeof someSymbol === "symbol";
}
var a_Symbol = Symbol("hey!");
var totally_Not_A_Symbol = "hey";
console.log(isSymbol(a_Symbol)); //true
console.log(isSymbol(totally_Not_A_Symbol)); //false