tipos - ¿Por qué puedo usar una función antes de que esté definida en JavaScript?
retornar valor de una funcion javascript (7)
Este código siempre funciona, incluso en diferentes navegadores:
function fooCheck() {
alert(internalFoo()); // We are using internalFoo() here...
return internalFoo(); // And here, even though it has not been defined...
function internalFoo() { return true; } //...until here!
}
fooCheck();
Sin embargo, no pude encontrar una sola referencia a por qué debería funcionar. Lo vi por primera vez en la nota de presentación de John Resig, pero solo se mencionó. No hay explicación allí ni en ninguna parte para el caso.
¿Puede alguien alumbrarme?
Algunos idiomas tienen el requisito de que los identificadores deben definirse antes de su uso. Una razón para esto es que el compilador usa una sola pasada en el código fuente.
Pero si hay múltiples pases (o se posponen algunos cheques) puede vivir perfectamente sin ese requisito. En este caso, el código probablemente se lea primero (e interprete) y luego se establecen los enlaces.
El cuerpo de la función "internalFoo" necesita ir a algún lugar en el tiempo de análisis, de modo que cuando el intérprete de JS lea el código (también conocido como análisis sintáctico), se crea la estructura de datos para la función y se asigna el nombre.
Solo más tarde, cuando se ejecuta el código, JavaScript realmente intenta averiguar si existe "internalFoo" y qué es, si se puede invocar, etc.
El navegador lee su HTML de principio a fin y puede ejecutarlo a medida que se lee y se analiza en fragmentos ejecutables (declaraciones de variables, definiciones de funciones, etc.), pero en cualquier momento solo puede usar lo que se ha definido en el html antes de ese punto.
Esto es diferente de otros contextos de programación que procesan (compilan) todo su código fuente, lo vinculan con las bibliotecas que necesita y construyen un módulo ejecutable, en cuyo punto comienza la ejecución.
Puede definir funciones que se refieren a elementos (variables, otras funciones, etc.) que se definen más adelante, pero no puede ejecutar esas funciones hasta que todas las piezas estén disponibles.
A medida que se familiarice con JavaScript, se volverá íntimamente consciente de su necesidad de escribir las cosas en la secuencia correcta.
Revisión: para confirmar la respuesta aceptada (arriba), use Firebug para recorrer la sección de guiones de una página web. Verá que pasa de la función a la función, visitando solo la primera línea, antes de que realmente ejecute cualquier código.
La declaración de function
es mágica y hace que su identificador se vincule antes de que se ejecute cualquier cosa en su bloque de código *.
Esto difiere de una asignación con una expresión de function
, que se evalúa en orden descendente normal.
Si cambiaste el ejemplo para decir:
var internalFoo = function() { return true; };
dejaría de funcionar.
La declaración de la función está sintácticamente bastante separada de la expresión de la función, a pesar de que se ven casi idénticas y pueden ser ambiguas en algunos casos.
Esto está documentado en el estándar ECMAScript , sección 10.1.3 . Desafortunadamente ECMA-262 no es un documento muy legible, ¡incluso para estándares estándares!
*: la función que contiene, bloque, módulo o script.
Por la misma razón, lo siguiente siempre colocará a foo
en el espacio de nombres global:
if (test condition) {
var foo;
}
Se llama HOISTING - Invoca (llama) una función antes de donde se ha definido.
Dos tipos diferentes de funciones sobre las que quiero escribir son:
Funciones de expresión y funciones de desaceleración
Funciones de expresión:
Una expresión de función se puede almacenar en una variable para que no necesiten nombres de función. También se nombrarán como una función anónima (una función sin nombre).
Para invocar (llamar) siempre se necesita usar un nombre de variable . Este tipo de funciones no funcionarán si las llamadas anteriores a donde se ha definido significan que el Levantamiento no está ocurriendo aquí. Siempre debemos definir primero la función de expresión y luego invocarla.
let lastName = function (family) { console.log("My last name is " + family); }; let x = lastName("Lopez");
Así es como puedes escribir en ECMAScript 6:
lastName = (family) => console.log("My last name is " + family); x = lastName("Lopez");
Funciones de desaceleración:
Las funciones declaradas con la siguiente sintaxis no se ejecutan inmediatamente. Se "guardan para un uso posterior" y se ejecutarán más tarde, cuando se invoquen (invoquen). Este tipo de funciones funcionan si las llamas ANTES o DESPUÉS de donde se han definido. Si llama a una función de desaceleración antes de donde se ha definido - Elevación - funciona correctamente.
function Name(name) { console.log("My cat''s name is " + name); } Name("Chloe");
Ejemplo de elevación:
Name("Chloe"); function Name(name) { console.log("My cat''s name is " + name); }
Solo he usado JavaScript un poco. No estoy seguro si esto ayudará, pero se ve muy similar a lo que está hablando y puede dar una idea:
http://www.dustindiaz.com/javascript-function-declaration-ambiguity/