No contexto de programação em JavaScript, o “tipo de dado simbólico”, ou simplesmente “tipo de dado Symbol”, é uma característica introduzida no ECMAScript 6 (também conhecido como ES6) para representar valores únicos e imutáveis. Um valor do tipo Symbol pode ser criado utilizando a função Symbol()
, que retorna um valor Symbol primitivo.
Um Symbol é um tipo primitivo, o que significa que não é uma instância de um objeto e não possui métodos próprios. Isso o torna diferente de tipos de dados como objetos, arrays, strings, etc. Um aspecto importante dos Symbols é que eles são únicos. Cada valor Symbol é único e diferente de qualquer outro Symbol, mesmo que tenham a mesma descrição.
Um Symbol pode opcionalmente ser criado com uma descrição, que é uma string que ajuda a identificar ou descrever o Symbol, mas essa descrição não afeta sua unicidade. Por exemplo:
javascriptconst symbol1 = Symbol();
const symbol2 = Symbol('descrição');
console.log(typeof symbol1); // "symbol"
console.log(typeof symbol2); // "symbol"
No exemplo acima, symbol1
e symbol2
são dois Symbols distintos. Embora symbol2
tenha uma descrição, isso não o torna igual a symbol1
.
Os Symbols são frequentemente usados para adicionar propriedades a objetos sem o risco de colisão de nomes de propriedades. Isso ocorre porque Symbols são sempre únicos, mesmo que suas descrições sejam iguais. Por exemplo:
javascriptconst meuSimbolo = Symbol('chave');
const outroSimbolo = Symbol('chave');
const objeto = {};
objeto[meuSimbolo] = 'valor associado ao meuSimbolo';
objeto[outroSimbolo] = 'valor associado ao outroSimbolo';
console.log(objeto[meuSimbolo]); // "valor associado ao meuSimbolo"
console.log(objeto[outroSimbolo]); // "valor associado ao outroSimbolo"
Neste exemplo, embora meuSimbolo
e outroSimbolo
tenham a mesma descrição, eles são distintos e não colidem como propriedades do objeto.
Os Symbols também são frequentemente usados como chaves de propriedade para definir propriedades de métodos internos em objetos, como os métodos definidos pelo ECMAScript. Isso ajuda a evitar a exposição de funcionalidades internas que não devem ser acessadas diretamente pelo código do usuário. Por exemplo, no contexto de iteradores, o Symbol.iterator é frequentemente usado para definir um método que retorna um iterador para um objeto, permitindo a iteração sobre seus elementos.
Embora os Symbols sejam úteis em várias situações, eles também têm algumas peculiaridades. Por exemplo, ao iterar sobre as propriedades de um objeto usando for...in
ou Object.keys()
, as propriedades cujas chaves são Symbols não são incluídas na iteração. Isso ocorre porque os Symbols são considerados propriedades não enumeráveis por padrão. No entanto, é possível acessar propriedades Symbol usando métodos como Object.getOwnPropertySymbols()
.
Em resumo, o tipo de dado Symbol em JavaScript é uma adição valiosa ao conjunto de tipos primitivos da linguagem. Sua capacidade de representar valores únicos e imutáveis, juntamente com sua utilidade na definição de propriedades de objetos sem risco de colisão de nomes, o torna uma ferramenta poderosa para desenvolvedores.
“Mais Informações”
O tipo de dados simbólico, conhecido como Symbol, é uma adição significativa à linguagem de programação JavaScript, introduzida na especificação ECMAScript 6 (também conhecida como ES2015). Este tipo de dados permite a criação de valores únicos e imutáveis, que podem ser utilizados como identificadores para propriedades de objetos. Sua introdução visa resolver algumas limitações relacionadas à utilização de strings como chaves de propriedades em objetos, além de oferecer uma forma mais segura de definir propriedades customizadas.
Um símbolo é uma primitiva, o que significa que ele é um tipo de dado básico e não um objeto. Isso implica que símbolos não podem ser instanciados com a palavra-chave new
. Eles são criados utilizando a função global Symbol()
, que retorna um valor único a cada invocação, mesmo que com os mesmos argumentos. Por exemplo:
javascriptconst simbolo1 = Symbol();
const simbolo2 = Symbol('descricao');
console.log(typeof simbolo1); // output: "symbol"
console.log(simbolo1 === simbolo2); // output: "false"
Neste exemplo, simbolo1
e simbolo2
são símbolos distintos. O símbolo simbolo2
recebe uma descrição opcional “descricao”, que é útil apenas para fins de depuração e não afeta a identidade do símbolo.
Uma característica importante dos símbolos é que eles são únicos. Isso significa que mesmo que dois símbolos tenham a mesma descrição, eles ainda são considerados diferentes:
javascriptconst simbolo1 = Symbol('foo');
const simbolo2 = Symbol('foo');
console.log(simbolo1 === simbolo2); // output: "false"
Os símbolos podem ser utilizados como chaves de propriedades em objetos, fornecendo uma maneira de evitar colisões de nomes de propriedades, especialmente em situações onde diferentes partes do código podem estar trabalhando com o mesmo objeto. Por exemplo:
javascriptconst meuObjeto = {};
const chave1 = Symbol('chave');
const chave2 = Symbol('chave');
meuObjeto[chave1] = 'valor1';
meuObjeto[chave2] = 'valor2';
console.log(meuObjeto[chave1]); // output: "valor1"
console.log(meuObjeto[chave2]); // output: "valor2"
Neste exemplo, chave1
e chave2
são símbolos distintos, então eles não sobrescrevem um ao outro quando usados como chaves de propriedade no objeto meuObjeto
.
Uma das principais vantagens de usar símbolos como chaves de propriedades é que eles não são acessíveis através dos métodos de iteração padrão, como for...in
e Object.keys()
. Isso pode ser útil para definir propriedades privadas em objetos, já que elas não serão facilmente acessíveis fora do escopo do objeto. Por exemplo:
javascriptconst meuObjeto = {
[Symbol('chavePrivada')]: 'valorPrivado'
};
console.log(Object.keys(meuObjeto)); // output: "[]"
Neste caso, a propriedade definida com um símbolo como chave não será retornada pelo método Object.keys()
, mantendo-a “privada” em relação a iteração padrão de propriedades.
Além disso, existem alguns símbolos predefinidos em JavaScript, que são acessíveis através do objeto global Symbol
. Por exemplo:
Symbol.iterator
: Um símbolo que define um método que retorna um iterador para o objeto. É utilizado em estruturas de dados iteráveis, como arrays e objetos Set.Symbol.species
: Um símbolo que especifica uma função de construtor para criar objetos derivados. É usado em métodos comoArray.prototype.map()
eArray.prototype.filter()
para garantir que as subclasses sejam corretamente instanciadas.Symbol.match
,Symbol.replace
,Symbol.search
eSymbol.split
: Símbolos usados para personalizar o comportamento de expressões regulares em JavaScript.
Esses são apenas alguns exemplos do uso de símbolos em JavaScript. Eles fornecem uma maneira eficaz de criar identificadores únicos e evitar colisões de nomes de propriedades em objetos, além de permitir a definição de propriedades “privadas” que não são facilmente acessíveis fora do escopo do objeto.