Prefacio
En ECMAScript, hay dos métodos más utilizados para crear objetos de función, a saber, utilizando expresiones de funciones o utilizando declaraciones de funciones. En este sentido, la especificación de ECMAScript deja en claro que las declaraciones de funciones siempre deben llevar un identificador, que es lo que llamamos el nombre de la función, y se pueden omitir expresiones de función. Echemos un vistazo a la introducción detallada a las diferencias entre los dos.
¿Qué es la declaración de función?
La declaración de función puede definir variables de función nombradas sin asignar valores a las variables. La declaración de función es una estructura independiente que no puede anidarse en módulos no funcionales. Se puede comparar con la declaración variable. Así como la declaración variable debe comenzar con "var", la declaración de función debe comenzar con "función".
Por ejemplo
Function Bar () {return 3;}ECMA 5 (13.0) Sintaxis de definición:
function Identifier ( FormalParameterList[opt] ) { FunctionBody }
Los nombres de las funciones están disponibles dentro de su propio alcance y alcance principal (de lo contrario, la función no estará disponible).
function bar () {return 3;} bar () // 3bar // función¿Qué es la expresión de la función?
La expresión de la función define una función como parte de una declaración de expresión (generalmente asignación variable). Las funciones definidas por la expresión de la función pueden ser nombradas o anónimas. La expresión de la función no puede comenzar con la "función" (los siguientes ejemplos de autostros deben encerrarse en los soportes).
Por ejemplo
// función anónima expresionVar a = function () {return 3;} // function expressionVar a = function bar () {return 3;} // autoinvocación de la expresión de funciones (función sayshello () {alert ("¡Hola!");}) ();ECMA 5 (13.0) Sintaxis de definición:
function Identifieropt ( FormalParameterList[opt] ) { FunctionBody }
(Esta definición se siente incompleta porque ignora una condición: la declaración periférica es una expresión y no comienza con "función")
Los nombres de las funciones (si los hay) no están disponibles fuera del alcance (en comparación con la declaración de función).
Entonces, ¿qué es la declaración de función?
La declaración de función es a veces otra forma de declaración de función. Pero Kangax señala que en Mozilla, la declaración de funciones es una extensión de la declaración de función, lo que permite que la declaración de declaración de funciones se use en cualquier lugar que permita el uso de declaraciones. Sin embargo, la declaración de función no es el estándar ahora, por lo que no se recomienda utilizar en el desarrollo de productos.
Comencemos con algunas pequeñas pruebas. ¿Adivina qué aparecerá en las siguientes situaciones?
Pregunta 1:
function foo () {function bar () {return 3; } Barra de retorno (); función bar () {return 8; }} alert (foo ());Pregunta 2:
function foo () {var bar = function () {return 3; }; Barra de retorno (); var bar = function () {return 8; };} alert (foo ());Pregunta 3:
alert (foo ()); function foo () {var bar = function () {return 3; }; Barra de retorno (); var bar = function () {return 8; };}Pregunta 4:
function foo () {return bar (); var bar = function () {return 3; }; var bar = function () {return 8; };} alert (foo ());Si su respuesta no es 8, 3, 3 y [Tipo de error: la barra no es una función], continúe leyendo ... (incluso si responde correctamente, debe continuar leyendo)
Ahora explicemos la prueba anterior.
La pregunta 1 usa la declaración de función, lo que significa que son izenados ...
Espera, ¿qué está elevando?
Aquí hay una cita de Ben Cherry: "La declaración de función y la variable de función generalmente se mueven ('Alzado') a la parte superior del alcance actual por el intérprete JavaScript".
Cuando se promueve la declaración de función, todo el cuerpo de la función se promoverá en consecuencia, por lo que el código de la pregunta 1 se ejecuta así después de ser explicado por el intérprete:
// ** secuencia de procesamiento simulada para la pregunta 1 ** función foo () {// Definir barra una vez la barra de la función () {return 3; } // redefinir it Function Bar () {return 8; } // devuelve su barra de retorno de invocación (); // 8} alerta (foo ());Sin embargo, a menudo se nos dice que el código detrás de la declaración de retorno no puede ejecutarse ...
Durante la ejecución de JavaScript, hay dos conceptos: el contexto (ECMA 5 lo descompone en LéxicalEnvironment, VariableNment y thisusning) y el proceso (una serie de declaraciones llamadas en secuencia). Cuando el programa ingresa al dominio de ejecución, la declaración causa variableSonvironment. Son diferentes de la declaración (como la devolución) y no siguen las reglas de ejecución de la declaración.
¿Se promovirá la expresión de la función?
Depende de la expresión. Por ejemplo, la primera expresión en la pregunta 2:
var bar = function () {return 3;};La (barra var) a la izquierda del signo igual es la declaración variable. Se promoverá la declaración de variable, pero la expresión de asignación no lo hará. Entonces, cuando se promueve la barra, el intérprete se inicializará así: var bar = indefinido. La definición de función en sí no será promovida.
(ECMA 5 12.2 Las variables con InitialZier se asignan por asignación de expresión cuando se ejecuta la variBlestatement, no cuando se crea la variable).
Por lo tanto, el Código de la Pregunta 2 se ejecutará en el siguiente orden:
// ** Secuencia de procesamiento simulada para la pregunta 2 ** Función foo () {// Una declaración para cada función de expresión var bar = undefined; bar bar = indefinido; // La expresión de la primera función se ejecuta bar = function () {return 3; }; // La función creada por la expresión de la primera función se invoca barra de retorno (); // SEGUNDA FUNCIÓN Expresión no LACABLE} alert (foo ()); // 3Puede decir que esto puede explicarse, pero la respuesta a la pregunta 3 es incorrecta. Informaré un error al ejecutar Firebug.
Guarde el código en un archivo HTML e intente ejecutarlo en Firefox. O ejecutar en la consola IE8, Chrome o Safari. Obviamente, la consola Firebug no promoverá la función al ejecutar el código en el alcance "global" (en realidad no global, sino el alcance único "Firebug", solo intente ejecutar "esta ventana ==" en la consola Firebug).
La pregunta 3 y la pregunta 1 tienen una lógica similar. Esta vez se promovió la función FOO.
La pregunta 4 es muy simple, no hay una mejora de la función en absoluto ...
Se puede decir eso, pero si no hay mejoras en absoluto, el tipoguror estará "bar no definido" en lugar de "barra no es una función". De hecho, no hay una mejora de la función en este ejemplo, pero hay una mejora variable. Por lo tanto, Bar se declara al principio, pero su valor no está definido. Los otros códigos se ejecutan en orden.
// ** Secuencia de procesamiento simulada para la pregunta 4 ** Función foo () {// Una declaración para cada función de expresión var bar = undefined; bar bar = indefinido; Barra de retorno (); // typeError: "bar no definido" // ninguna expresión de función se alcanza} alerta (foo ());¿A qué más debes prestar atención?
El oficial prohíbe el uso de la declaración de función en módulos no funcionales (como si). Sin embargo, todos los navegadores lo apoyan, pero sus explicaciones son diferentes.
Por ejemplo, el siguiente fragmento de código arrojará un error en Firefox 3.6 porque interpreta la declaración de función como instrucción de función (ver arriba), por lo que X no está definido. Pero en IE8, Chrome 5 y Safari 5, la función X se devolverá (igual que la declaración de función estándar).
function foo () {if (false) {function x () {}; } return x;} alert (foo ());Se puede ver que el uso de la declaración de función puede causar confusión, entonces, ¿tiene alguna ventaja?
Podría decir que la declaración de función es bastante floja: si intenta usar una función antes de la declaración, la promoción puede corregir el orden para que la función pueda llamarse correctamente. Pero este tipo de flojencia no es propicio para la codificación rigurosa, y desde una perspectiva a largo plazo, es probable que promueva en lugar de prevenir accidentes. Después de todo, hay una razón por la que los programadores organizan declaraciones en un orden específico.
Entonces, ¿hay otras razones para apoyar la expresión de funciones?
¿Qué opinas?
1) La declaración de función parece que es imitar las declaraciones de métodos de estilo Java, pero los métodos Java no son los mismos que JavaScript. En JavaScript, las funciones son objetos vivos con valores. Los métodos Java son solo el almacenamiento de metadatos. Las siguientes dos piezas de código definen la función, pero solo se crea la expresión de la función como si se cree un objeto.
// Declaración de funciones Function add (a, b) {return a + b}; // function ExpressionVar add = function (a, b) {return a + b};2) La expresión de la función tiene más usos. La declaración de función solo puede existir en los huérfanos como una "declaración". Todo lo que puede hacer es crear una variable de objeto en el alcance actual. La expresión de la función, por definición, es parte de una gran estructura. Si desea crear funciones anónimas, agregue funciones a los prototipos o utilice funciones como propiedad de otros objetos, puede usar la expresión de funciones. Siempre que use aplicaciones avanzadas, como curry o componer, utiliza la expresión de funciones al crear nuevas funciones. La expresión de la función y la programación funcional son inseparables.
// función expresionVar sayshello = Alert.Curry ("¡Hola!");¿Hay algún inconveniente en la expresión de funciones?
La expresión de la función crea la mayoría de las funciones anónimas. Por ejemplo, la siguiente función es anónima, hoy es solo una referencia a una función anónima:
var hoy = function () {return new Date ()}¿Será esto problemático? No en la mayoría de los casos, pero como señaló Nick Fitzgerald, la depuración de funciones anónimas puede ser molesto. Recomienda usar expresiones de funciones de nombre (NFES) como el espacio de trabajo:
var hoy = function Today () {return new Date ()}Sin embargo, como dijo Asen Bozhilov (y la documentación de Kangax) NFES no se puede ejecutar correctamente por debajo de IE9.
en conclusión
Una declaración de función colocada al azar es engañosa y raramente (si las hay) situaciones, y asignar valores a variables con expresión de la función no puede reemplazar la declaración de función. Pero si se requiere una declaración de función, ponerla en la parte superior del alcance puede reducir la confusión. Nunca ponga la declaración de función en una declaración IF.
Habiendo dicho tanto, la declaración de función puede ser útil en su propia situación. No es nada. El rol Dogma es peligroso y a menudo hace que el código sea latido alrededor del monte. Más importante aún, comprende el concepto para que pueda decidir qué método crear la función en función de su propia situación. Lo anterior es todo el contenido de este artículo. Espero que este artículo sea útil para todos a este respecto.