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 de por qué debería funcionar. Vi esto por primera vez en la nota de presentación de John Resig, pero solo se mencionó. No hay explicación allí o en ningún lado para el caso.
¿Puede alguien alumbrarme?
javascript
function
Edu Felipe
fuente
fuente
Respuestas:
La
function
declaración es mágica y hace que su identificador se vincule antes de que se ejecute algo en su bloque de código *.Esto difiere de una asignación con una
function
expresión, que se evalúa en orden normal de arriba hacia abajo.Si cambiaste el ejemplo para decir:
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 parecen 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 los estándares estándares!
*: la función que contiene, bloque, módulo o script.
fuente
Se llama LEVANTAMIENTO - Invocar (llamar) una función antes de que se haya definido.
Dos tipos diferentes de funciones sobre las que quiero escribir son:
Funciones de expresión y funciones de declaración
Funciones de expresión:
Las expresiones de funciones se pueden almacenar en una variable para que no necesiten nombres de funciones. También se nombrarán como una función anónima (una función sin nombre).
Para invocar (llamar) estas funciones siempre necesitan un nombre de variable . Este tipo de función no funcionará si se llama antes de que se haya definido, lo que significa que el levantamiento no está sucediendo aquí. Siempre debemos definir primero la función de expresión y luego invocarla.
Así es como puedes escribirlo en ECMAScript 6:
Funciones de declaración:
Las funciones declaradas con la siguiente sintaxis no se ejecutan inmediatamente. Se "guardan para su uso posterior" y se ejecutarán más tarde, cuando se invoquen (se invoquen). Este tipo de función funciona si lo llama ANTES o DESPUÉS de donde se ha definido. Si llama a una función de declaración antes de que se haya definido, la elevación funciona correctamente.
Ejemplo de elevación:
fuente
let fun = theFunction; fun(); function theFunction() {}
también funcionará (Node y navegadores)El navegador lee su HTML de principio a fin y puede ejecutarlo tal como se lee y 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 script antes de ese punto.
Esto es diferente de otros contextos de programación que procesan (compilan) todo su código fuente, quizás lo vinculen con cualquier biblioteca que necesite para resolver referencias y construyan un módulo ejecutable, en cuyo punto comienza la ejecución.
Su código puede hacer referencia a objetos con nombre (variables, otras funciones, etc.) que se definen más adelante, pero no puede ejecutar el código de referencia hasta que todas las piezas estén disponibles.
A medida que se familiarice con JavaScript, se dará cuenta de su necesidad de escribir las cosas en la secuencia adecuada.
Revisión: para confirmar la respuesta aceptada (arriba), use Firebug para recorrer la sección de secuencia de comandos de una página web. Verá que salta de una función a otra, visitando solo la primera línea, antes de que realmente ejecute cualquier código.
fuente
Algunos idiomas requieren que los identificadores se definan 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 varios pases (o se aplazan algunos controles), puede vivir perfectamente sin ese requisito. En este caso, el código probablemente se lea primero (y se interprete) y luego se establecerán los enlaces.
fuente
Solo he usado JavaScript un poco. No estoy seguro de si esto ayudará, pero se parece mucho a lo que está hablando y puede dar alguna idea:
http://www.dustindiaz.com/javascript-function-declaration-ambiguity/
fuente
El cuerpo de la función "internalFoo" debe ir a algún lugar en el momento del análisis, de modo que cuando el intérprete JS lee el código (también conocido como análisis), 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 y si se puede llamar, etc.
fuente
Por la misma razón, lo siguiente siempre se colocará
foo
en el espacio de nombres global:fuente
if
bloque no crea un ámbito, mientras que unfunction()
bloque siempre crea uno. La verdadera razón fue que la definición de los nombres globales de JavaScript ocurre en la fase de compilación, de modo que incluso si el código no se ejecuta, el nombre está definido. (Lo siento, tardó tanto en comentar)