tl; dr Si no está llamando a nada hasta que todo se cargue, debería estar bien.
Editar: Para obtener una descripción general que también cubre algunas declaraciones de ES6 ( let
, const
): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet
Este comportamiento extraño depende de
- Cómo se definen las funciones y
- Cuando los llames.
He aquí algunos ejemplos.
bar(); //This won't throw an error
function bar() {}
foo(); //This will throw an error
var foo = function() {}
bar();
function bar() {
foo(); //This will throw an error
}
var foo = function() {}
bar();
function bar() {
foo(); //This _won't_ throw an error
}
function foo() {}
function bar() {
foo(); //no error
}
var foo = function() {}
bar();
¡Esto se debe a algo llamado izar !
Hay dos formas de definir funciones: declaración de función y expresión de función . La diferencia es molesta y diminuta, así que digamos algo ligeramente incorrecto: si lo escribes como function name() {}
, es una declaración , y cuando lo escribes como var name = function() {}
(o una función anónima asignada a una devolución, cosas así), es una expresión de función .
Primero, veamos cómo se manejan las variables:
var foo = 42;
//the interpreter turns it into this:
var foo;
foo = 42;
Ahora, cómo se manejan las declaraciones de funciones :
var foo = 42;
function bar() {}
//turns into
var foo; //Insanity! It's now at the top
function bar() {}
foo = 42;
Las var
declaraciones "arrojan" la creación de foo
al principio, pero aún no le asignan el valor. La declaración de la función viene a continuación en la línea y finalmente se le asigna un valor foo
.
¿Y que hay de esto?
bar();
var foo = 42;
function bar() {}
//=>
var foo;
function bar() {}
bar();
foo = 42;
Solo la declaración de foo
se mueve a la parte superior. La asignación viene solo después de que bar
se realiza la llamada a , donde estaba antes de que ocurriera todo el izado.
Y finalmente, por concisión:
bar();
function bar() {}
//turns to
function bar() {}
bar();
Ahora, ¿qué pasa con las expresiones de función ?
var foo = function() {}
foo();
//=>
var foo;
foo = function() {}
foo();
Al igual que las variables regulares, primero foo
se declara en el punto más alto del alcance, luego se le asigna un valor.
Veamos por qué el segundo ejemplo arroja un error.
bar();
function bar() {
foo();
}
var foo = function() {}
//=>
var foo;
function bar() {
foo();
}
bar();
foo = function() {}
Como hemos visto antes, sólo foo
se levanta la creación de , la asignación viene donde apareció en el código "original" (no-alzado). Cuando bar
se llama, es antes de que foo
se le asigne un valor, entonces foo === undefined
. Ahora, en el cuerpo de función de bar
, es como si lo estuviera haciendo undefined()
, lo que arroja un error.