Esta publicación trata sobre el Symbol()
, suministrado con ejemplos reales que pude encontrar / hacer y hechos y definiciones que pude encontrar.
TLDR;
El Symbol()
es el tipo de datos, introducido con el lanzamiento de ECMAScript 6 (ES6).
Hay dos hechos curiosos sobre el símbolo.
el primer tipo de datos y solo el tipo de datos en JavaScript que no tiene literal
cualquier variable, definida con Symbol()
, obtiene contenido único, pero no es realmente privado .
cualquier dato tiene su propio Símbolo, y para los mismos datos los Símbolos serían los mismos . Más información en el siguiente párrafo, de lo contrario no es un TLRD; :)
¿Cómo inicializo el símbolo?
1. Para obtener un identificador único con un valor depurable
Puedes hacerlo de esta manera:
var mySymbol1 = Symbol();
O de esta manera:
var mySymbol2 = Symbol("some text here");
La "some text here"
cadena no se puede extraer del símbolo, es solo una descripción para fines de depuración. No cambia el comportamiento del símbolo de ninguna manera. Aunque, podría console.log
hacerlo (lo cual es justo, ya que el valor es para la depuración, para no confundir ese registro con alguna otra entrada de registro):
console.log(mySymbol2);
// Symbol(some text here)
2. Para obtener un símbolo para algunos datos de cadena
En este caso, el valor del símbolo se tiene realmente en cuenta y de esta manera dos símbolos pueden no ser únicos.
var a1 = Symbol.for("test");
var a2 = Symbol.for("test");
console.log(a1 == a2); //true!
Llamemos a esos símbolos símbolos de "segundo tipo". No se cruzan con los símbolos de "primer tipo" (es decir, los definidos con Symbol(data)
) de ninguna manera.
Los siguientes dos párrafos pertenecen solo al símbolo de primer tipo .
¿Cómo me beneficio al usar Symbol en lugar de los tipos de datos más antiguos?
Primero consideremos un objeto, un tipo de datos estándar. Podríamos definir algunos pares clave-valor allí y tener acceso a los valores especificando la clave.
var persons = {"peter":"pan","jon":"doe"};
console.log(persons.peter);
// pan
¿Qué pasa si tenemos dos personas con el nombre de Peter?
Haciendo esto:
var persons = {"peter":"first", "peter":"pan"};
No tendría mucho sentido.
Entonces, parece ser un problema de dos personas absolutamente diferentes que tienen el mismo nombre. Entonces veamos nuevo Symbol()
. Es como una persona en la vida real: cualquier persona es única , pero sus nombres pueden ser iguales. Definamos dos "personas".
var a = Symbol("peter");
var b = Symbol("peter");
Ahora tenemos dos personas diferentes con el mismo nombre. ¿Son nuestras personas realmente diferentes? Son; puedes verificar esto:
console.log(a == b);
// false
¿Cómo nos beneficiamos allí?
Podemos hacer dos entradas en su objeto para las diferentes personas y no pueden confundirse de ninguna manera.
var firstPerson = Symbol("peter");
var secondPerson = Symbol("peter");
var persons = {[firstPerson]:"first", [secondPerson]:"pan"};
Nota:
Sin embargo, vale la pena notar que al encadenar el objeto JSON.stringify
se eliminarán todos los pares inicializados con un Símbolo como clave.
La ejecución Object.keys
tampoco devolverá tales Symbol()->value
pares.
Usando esta inicialización, es absolutamente imposible confundir las entradas para la primera y la segunda persona. Llamar console.log
a ellos mostrará correctamente sus segundos nombres.
console.log(persons[a]);
// first
console.log(persons[b]);
// pan
Cuando se usa en un objeto, ¿cómo es diferente en comparación con la definición de propiedad no enumerable?
De hecho, ya existía una forma de definir una propiedad para ocultar Object.keys
y enumerar. Aquí está:
var anObject = {};
var fruit = "apple";
Object.defineProperty( anObject, fruit, {
enumerable: false,
value: "green"
});
¿Qué diferencia Symbol()
trae allí? La diferencia es que aún puede obtener la propiedad definida Object.defineProperty
de la manera habitual:
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //green
console.log(anObject.apple); //green
Y si se define con Symbol como en el párrafo anterior:
fruit = Symbol("apple");
Tendrá la capacidad de recibir su valor solo si conoce su variable, es decir
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //undefined
console.log(anObject.apple); //undefined
Además, definir otra propiedad bajo la clave "apple"
hará que el objeto descarte la anterior (y si está codificada, podría arrojar un error). Entonces, ¡no más manzanas! Eso es una lástima. Al referirse al párrafo anterior, los Símbolos son únicos y definen una clave que Symbol()
lo hará único.
Conversión de tipo y verificación
A diferencia de otros tipos de datos, es imposible convertirlos Symbol()
a cualquier otro tipo de datos.
Es posible "hacer" un símbolo basado en un tipo de datos primitivo llamando Symbol(data)
.
En términos de verificar el tipo, nada cambia.
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