La expresión lambda de C # también tiene cierres, pero rara vez es discutida por las comunidades o libros de C #. Veo que muchas más personas y libros de JavaScript hablan sobre sus cierres que en el mundo de C #. ¿Porqué es eso?
c#
javascript
closures
TomCaps
fuente
fuente
Respuestas:
Debido a que JavaScript no tiene características como los espacios de nombres, y puede desordenar fácilmente con todo tipo de objetos globales.
Por lo tanto, es importante poder aislar algún código en su propio entorno de ejecución. Los cierres son perfectos para eso.
Este uso del cierre no tiene sentido en un lenguaje como C # donde tiene espacios de nombres, clases, etc. para aislar el código y no poner todo en el ámbito global.
Una práctica muy común para el código javascript es escribirlo así:
Como puede ver, esta es una declaración de función anónima, seguida inmediatamente por su ejecución. Por lo tanto, es imposible acceder a todo lo definido dentro de la función desde el exterior, y no arruinará el alcance global. El contexto de ejecución de esta función permanecerá activo mientras algún código lo use, como funciones anidadas definidas dentro de este contexto, que puede pasar como devolución de llamada o lo que sea.
Javascript es un lenguaje muy diferente a C #. No está orientado a objetos, está orientado a prototipos. Esto lleva a prácticas muy diferentes al final.
De todos modos, los cierres son buenos, ¡así que úsalos, incluso en C #!
EDITAR: Después de discutir sobre el chat de stackoverflow, creo que esta respuesta debe ser precisa.
La función en el código de muestra no es un cierre. Sin embargo, esta función puede definir variables locales y funciones anidadas. Todas las funciones anidadas que usan estas variables locales son cierres.
Esto es útil para compartir algunos datos a través de un conjunto de funciones sin alterar el alcance global. Este es el uso más común de cierre en javascript.
Los cierres son mucho más poderosos que simplemente compartir algunos datos como este, pero seamos realistas, la mayoría de los programadores no saben nada sobre programación funcional. En C #, habría utilizado una clase o un espacio de nombres para este tipo de uso, pero JS no proporciona esta funcionalidad.
Con el cierre, puede hacer mucho más que solo proteger el alcance global, pero esto es lo que verá en el código fuente de JS.
fuente
Probablemente porque las implementaciones populares de la orientación a objetos de JavaScript dependen de los cierres. Veamos un ejemplo simple:
Los métodos
getValue
yincrease
de hecho son cierres, encapsulando la variablevalue
.fuente
Porque muchas de las bibliotecas que hacen que JavaScript sea soportable los usan.
Eche un vistazo a JQuery , Prototype o MooTools , solo por nombrar tres populares. Cada una de esas bibliotecas proporciona un
each
método para sus colecciones como la forma preferida de iteración, que utiliza una función de iterador. Esa función, al acceder a valores en el ámbito externo, será un cierre:Y no se detiene allí: las devoluciones de llamada en Ajax, el manejo de eventos en Ext.js, etc.todas toman funciones, y si no desea inflar su código con 100eds de funciones que se llaman exactamente una vez, los cierres son el camino a seguir.
fuente
console.log
se define en un ámbito externo, por lo queconsole
es una 'variable libre'. Y, ¿por qué es, en efecto, un bucle for, que no hace nada diferente, una mala práctica?Estoy de acuerdo con las otras respuestas de que la codificación "buena" con JavaScript depende más de los cierres. Sin embargo, además de eso, probablemente solo se trate de cuánto tiempo ha estado presente la función en cada idioma. JavaScript ha tenido básicamente cierres desde sus primeras implementaciones. C # por otro lado solo los ha tenido desde 3.0, que se lanzó con Visual Studio 2008.
Muchos programadores de C # con los que me encuentro todavía están trabajando en proyectos 2.0. E incluso si están trabajando en 3.0 o 4.0, a menudo todavía usan modismos 2.0. Amo los cierres; con suerte, se utilizarán más en C # a medida que el concepto se propague entre los desarrolladores de C #.
fuente
La razón principal es que C # está estáticamente tipado y las funciones solo tienen acceso a un entorno único predeterminado, lo que impide la utilidad de los cierres.
En JavaScript, por otro lado, los cierres permiten que las funciones se comporten como métodos cuando se accede como una propiedad de objeto y como objetos de primera clase, también se pueden inyectar en diferentes entornos que permiten que las subrutinas operen en diferentes contextos.
fuente
Una razón por la que tuve que aprender sobre ellos fue porque cuando estás recorriendo los elementos DOM (o algo realmente), quieres poder "cerrar" o "encapsular" el alcance variable. Como en el ejemplo publicado aquí: /programming/5606059/how-to-create-closure-in-loop-and-store-it-in-variable-for-later-execution
fuente