¿Por qué pasar grandes funciones anónimas como argumentos a otras funciones es tan ampliamente aceptado en JavaScript?

27

Tengo una opinión (que estoy seguro de que será compartida por algunos) de que pasar funciones anónimas que contienen más de unas pocas líneas de código, ya que los argumentos de otras funciones afectan drásticamente la legibilidad y la autodocumentación, hasta el punto en que siento que lo haría. sería mucho mejor para cualquiera que use el código para declarar una función con nombre. O al menos asigne esa función anónima a una variable antes de declarar la función principal

Sin embargo, muchas bibliotecas de JavaScript (jQuery, d3.js / NVD3.js) solo para dar un par de ejemplos, utilizan grandes funciones de esta manera.

¿Por qué es esto tan ampliamente aceptado en JavaScript? ¿Es una cuestión cultural, o hay ventajas que me estoy perdiendo, que harían que el uso sea más preferido que declarar una función con nombre?

Adam Copley
fuente
1
Probablemente tiene mucho que ver con el uso de cierres . También podría tener que ver con no querer exponer la función real al mundo exterior (razón por la cual es anónima).
Robert Harvey
3
@RobertHarvey En otras palabras, ¿es una solución alternativa para que JavaScript no sea público y privado ?
Mason Wheeler
2
En muchos lugares, una función anónima grande se lee más como un bloque y generalmente se siente bastante bien una vez que te acostumbras. Las reglas de alcance incluso apoyan la sensación de bloqueo.
55
@MasonWheeler: Eso depende de tu perspectiva. Un programador de Scheme o ECMAScript podría decir eso publicy privateson soluciones para no tener los cierres adecuados.
Jörg W Mittag
1
@ JörgWMittag Hooray para Racket, el patrocinador oficial de idiomas de XKCD 927.
Mason Wheeler

Respuestas:

23

Tres razones principales en las que puedo pensar:

  1. Acceso al alcance de los padres
  2. Intimidad
  3. Reducción de nombres definidos en ámbitos más altos

Acceso al ámbito principal: las definiciones de funciones en línea permiten que el código en línea tenga acceso a las variables definidas en los ámbitos principales. Esto puede ser muy útil para muchas cosas y puede reducir la cantidad o la complejidad del código si se hace correctamente.

Si coloca el código en una función definida fuera de este ámbito y luego llama al código, entonces tendría que pasar cualquier estado primario al que quisiera acceder a la función.

Privacidad: el código dentro de una definición anónima en línea es más privado y no puede ser llamado por otro código.

Reducción de nombres definidos en ámbitos más altos: Esto es más importante cuando se opera en el ámbito global, pero una declaración anónima en línea evita tener que definir un nuevo símbolo en el ámbito actual. Dado que Javascript no requiere de forma nativa el uso de espacios de nombres, es aconsejable evitar definir más símbolos globales de los mínimos necesarios.


Editorial: Parece haberse convertido en algo cultural en Javascript, donde declarar algo anónimamente en línea de alguna manera se considera "mejor" que definir una función y llamarla incluso cuando no se utiliza el acceso de ámbito primario. Sospecho que esto se debió inicialmente al problema de la contaminación del espacio de nombres global en Javascript, luego quizás debido a problemas de privacidad. Pero ahora se ha convertido en algo cultural y puede verse expresado en muchos cuerpos públicos de código (como los que usted menciona).

En lenguajes como C ++, la mayoría probablemente consideraría una práctica menos que ideal tener una función gigante que se extienda a través de muchas páginas / pantallas. Por supuesto, C ++ tiene un espacio de nombres incorporado, no proporciona acceso al ámbito primario y tiene características de privacidad, por lo que puede estar motivado por completo por la legibilidad / mantenibilidad, mientras que Javascript tiene que usar la expresión de código para lograr la privacidad y el acceso al ámbito primario. Entonces, JS parece haber sido motivado en una dirección diferente y se ha convertido en algo cultural dentro del idioma, incluso cuando las cosas que motivaron esa dirección no son necesarias en un caso específico.

jfriend00
fuente
Como un desarrollador de C ++ se mudó recientemente a JS por gran parte de mi trabajo, esta respuesta tiene mucho sentido, particularmente el punto de 'acceso de alcance primario': realmente tiene el poder de simplificar enormemente su código. Un punto crítico: C ++ proporciona acceso de alcance primario en C ++ 11 lambdas :) Sin embargo, definitivamente +1.
Comandante Coriander Salamander
8

Las funciones anónimas se utilizan para muchos más propósitos en JavaScript que en la mayoría de los idiomas.

Primero, se usan para el espacio de nombres y el alcance de bloque. Hasta hace poco, JavaScript carecía de módulos o de cualquier otro tipo de mecanismo de espacio de nombres, lo que ha llevado a utilizar funciones anónimas para proporcionar esa funcionalidad a través del patrón de módulo. No habría absolutamente ningún beneficio en nombrar estas funciones. En una escala menor, debido a la falta de alcance de bloque de JavaScript hasta hace poco, se utilizó un patrón similar para imitar el alcance de bloque; más notablemente en el cuerpo de bucles. Usar una función con nombre en este caso sería ofuscatorio activo.

En segundo lugar, y menos específicas de JavaScript, las funciones anónimas a menudo se usan con funciones de orden superior que imitan las estructuras de control. Por ejemplo, el eachmétodo de jQuery . Dudo que abstraiga cada cuerpo de bucle o if-branch en una función siempre que tenga más de unas pocas líneas de largo. La misma lógica se aplica en este caso.

Una razón final es que la programación basada en eventos es común en JavaScript, que tiende a conducir a un código de estilo de paso de continuación inadvertido . Realiza una llamada AJAX y registra una devolución de llamada que, cuando se ejecuta, realizará otra llamada AJAX y registrará una devolución de llamada, etc. . Una vez más, dudo que resuma cada pocas líneas de código de línea recta en una función.

También hay factores culturales y, por las razones anteriores, entre otras, las funciones anónimas son mucho más comunes en JavaScript que muchos otros idiomas y se usan de manera más cómoda / laxa que muchos otros idiomas.

Derek Elkins
fuente
Mis propias estructuras, tal vez ingenuas, en la codificación C ++ a veces han tomado principios de codificación basada en eventos y devoluciones de llamada de JavaScript a través de std :: function y lambdas. En mi caso, es parcialmente porque estoy haciendo código UI en C ++ y no quiero realizar operaciones de bloqueo. Tengo curiosidad por saber si las prácticas de JavaScript son simplemente útiles para cualquier persona, siempre que el lenguaje las admita bien.
Katana314