ACTUALIZACIÓN : Recientemente apareció un artículo brillante de Mozilla . Léelo si tienes curiosidad.
Como ya sabrán, planean incluir un nuevo tipo de Símbolo primitivo en ECMAScript 6 (sin mencionar algunas otras cosas locas). Siempre pensé que la :symbolnoción en Ruby es innecesaria; podríamos usar fácilmente cadenas simples, como lo hacemos en JavaScript. Y ahora deciden complicar las cosas en JS con eso.
No entiendo la motivación. ¿Podría alguien explicarme si realmente necesitamos símbolos en JavaScript?

privateypublicpalabras clave de atributos de clase que decidieron deshacerse de implementación de la clase más simple. En lugar dethis.x = xque se suponía que debías hacerpublic x = xy para variables privadasprivate y = y. Decidieron deshacerse de eso para una implementación de clase mucho más mínima. Symbol sería una solución alternativa necesaria para obtener propiedades privadas en la implementación mínima.Respuestas:
La motivación original para introducir símbolos en Javascript era habilitar propiedades privadas .
Desafortunadamente, terminaron siendo severamente degradados. Ya no son privados, ya que puede encontrarlos a través de la reflexión, por ejemplo, usando
Object.getOwnPropertySymbolso proxies.Ahora se conocen como símbolos únicos y su único uso previsto es evitar conflictos de nombres entre propiedades. Por ejemplo, el propio ECMAScript ahora puede introducir ganchos de extensión a través de ciertos métodos que puede colocar en objetos (por ejemplo, para definir su protocolo de iteración) sin arriesgarlos a chocar con los nombres de usuario.
Es discutible si eso es lo suficientemente fuerte como una motivación para agregar símbolos al idioma.
fuente
Object.getOwnPropertySymbolsno es la única fuga; la más difícil es la capacidad de usar servidores proxy para interceptar el acceso a una propiedad "privada".Los símbolos no garantizan la verdadera privacidad, pero pueden usarse para separar las propiedades públicas e internas de los objetos. Tomemos un ejemplo donde podemos usar
Symbolpara tener propiedades privadas.Tomemos un ejemplo donde una propiedad de un objeto no es privada.
Arriba, la
Petpropiedad de la clasetypeno es privada. Para hacerlo privado, tenemos que crear un cierre. El siguiente ejemplo ilustra cómo podemos hacertypeprivado el uso de un cierre.Desventaja del enfoque anterior: Estamos introduciendo un cierre adicional para cada
Petinstancia creada, lo que puede dañar el rendimiento.Ahora te presentamos
Symbol. Esto puede ayudarnos a hacer que una propiedad sea privada sin usar cierres innecesarios adicionales. Ejemplo de código a continuación:fuente
_no garantiza una verdadera privacidad, pero puede usarse para separar las propiedades públicas e internas de los objetos. En otras palabras, respuesta inútil.Symbolsson un tipo de objeto nuevo y especial que se puede usar como un nombre de propiedad único en los objetos. Usar enSymbollugar destring's permite que diferentes módulos creen propiedades que no entren en conflicto entre sí.Symbolstambién se puede hacer privado, de modo que cualquiera que aún no tenga acceso directo a la propiedad no pueda acceder a sus propiedadesSymbol.SymbolsSon una nueva primitiva . Al igual que elnumber,stringybooleanprimitivas,Symboltienen una función que puede ser utilizado para crearlos. A diferencia de las otras primitivas,Symbolsno tienen una sintaxis literal (por ejemplo, cómostringtiene'') - la única manera de crear ellos es elSymbolconstructor de la siguiente manera:En realidad,
Symbolson solo una forma ligeramente diferente de adjuntar propiedades a un objeto: podría proporcionar fácilmente losSymbolsmétodos conocidos como estándar, tal comoObject.prototype.hasOwnPropertyaparece en todo lo que heredaObject.Estos son algunos de los beneficios del
Symboltipo primitivo.Symbolstener depurabilidad incorporadaSymbolsse puede dar una descripción, que en realidad solo se usa para la depuración para hacer la vida un poco más fácil al iniciar sesión en una consola.Symbolspuede usarse comoObjectllavesAquí es donde se
Symbolpone realmente interesante. Están fuertemente entrelazados con objetos.Symbolpuede asignarse como claves a objetos, lo que significa que puede asignar un número ilimitado de objetos únicosSymbola un objeto y garantizar que nunca entren en conflicto con lasstringteclas u otros objetos únicosSymbols.Symbolsse puede usar como un valor único.Supongamos que usted tiene una biblioteca de registro, que incluye múltiples niveles de registro, tales como
logger.levels.DEBUG,logger.levels.INFO,logger.levels.WARNy así sucesivamente. En el código ES5 le gustaría hacer estosstrings (sologger.levels.DEBUG === 'debug') onumbers (logger.levels.DEBUG === 10). Ambos no son ideales ya que esos valores no son valores únicos, ¡pero sí loSymbolson! Entonceslogger.levelssimplemente se convierte en:Lea más en este gran artículo .
fuente
log.levels = {DEBUG: Symbol('debug')y no simplementelog.levels = {DEBUG:'debug'}. Al final es lo mismo. Creo que vale la pena mencionar que los símbolos son invisibles al iterar sobre las teclas de un objeto. esa es su "cosa"{}y lograr el mismo resultado (como valor único), o tal vez se prefiere un literal en ese proyecto, o puede decir que uno necesita leer el documento primero.) I personalmente creo que proporciona una buena legibilidad de significado único en el códigoSymbol("some message")convierte en un{message:'some message'}objeto posiblemente mejor aquí, ya que puede agregar múltiples campos.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:
O de esta manera:
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íaconsole.loghacerlo (lo cual es justo, ya que el valor es para la depuración, para no confundir ese registro con alguna otra entrada de registro):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.
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.
¿Qué pasa si tenemos dos personas con el nombre de Peter?
Haciendo esto:
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".Ahora tenemos dos personas diferentes con el mismo nombre. ¿Son nuestras personas realmente diferentes? Son; puedes verificar esto:
¿Cómo nos beneficiamos allí?
Podemos hacer dos entradas en su objeto para las diferentes personas y no pueden confundirse de ninguna manera.
Usando esta inicialización, es absolutamente imposible confundir las entradas para la primera y la segunda persona. Llamar
console.loga ellos mostrará correctamente sus segundos nombres.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.keysy enumerar. Aquí está:¿Qué diferencia
Symbol()trae allí? La diferencia es que aún puede obtener la propiedad definidaObject.definePropertyde la manera habitual:Y si se define con Symbol como en el párrafo anterior:
Tendrá la capacidad de recibir su valor solo si conoce su variable, es decir
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 queSymbol()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.
fuente
Así es como lo veo. Los símbolos proporcionan 'un nivel adicional de privacidad' al evitar que las claves / propiedades de un objeto se expongan a través de algunos métodos populares como Object.keys () y JSON.stringify ().
Aunque dado un objeto per se, tales propiedades aún pueden exponerse a través de la reflexión, el proxy, Object.getOwnPropertySymbols (), etc., no hay medios naturales para acceder a ellos a través de algunos métodos directos, que a veces pueden ser suficientes desde una perspectiva OOP.
fuente
Un símbolo JS es un nuevo tipo de datos primitivos. Son tokens que sirven como identificaciones únicas . Se puede crear un símbolo usando el
Symbolconstructor. Tomemos, por ejemplo, este fragmento de MDN:A menudo es útil usar símbolos como claves de propiedad de objeto únicas, por ejemplo:
fuente
Fuente
fuente