Orden de elevación en JavaScript
hoisting (2)
Aunque el orden fue fijado por la especificación, como señala la respuesta aceptada, ese orden realmente no es tan importante.
-
var
declaracionesvar
son izadas, pero no su inicialización (si hay una). Una declaraciónvar
tiene efecto si el nombre ya está tomado por unafunction
u otra declaraciónvar
. -
function
definiciones defunction
se izan, no solo declarando el nombre, sino también su valor, es decir, la función.
Entonces, los siguientes dos fragmentos de código:
(function () {
console.log(typeof a);
var a = 1;
function a() { }
})();
y:
(function () {
console.log(typeof a);
function a() { }
var a = 1;
})();
... traducir a:
(function () {
function a() { }
var a;
console.log(typeof a);
a = 1;
})();
y respectivamente:
(function () {
var a;
function a() { }
console.log(typeof a);
a = 1;
})();
Los dos últimos son lo mismo realmente.
Si el motor procesa primero la declaración de
var
izada, entonces
a
es primero
undefined
pero luego se sobrescribe inmediatamente como función.
Si, por otro lado, la definición de la
function
se procesa primero, entonces la declaración
var
no tiene efecto.
En ambos escenarios, el resultado es el mismo.
function g () {
var x;
function y () {};
var z;
}
Me gustaría saber exactamente en qué orden se convierte el código anterior cuando se iza.
Teoría 1: El
orden entre
var
sy la
function
s permanece tal cual:
function g () {
var x;
function y () {};
var z;
}
Teoría 2:
var
s viene antes de la
function
s:
function g () {
var x;
var z;
function y () {};
}
Teoría 3: las
function
vienen antes que
var
s:
function g () {
function y () {};
var x;
var z;
}
¿Qué teoría es la correcta?
Primero se izan las funciones, luego las declaraciones de variables, según ECMAScript 5, sección 10.5 que especifica cómo ocurre el izado:
Primero tenemos el paso 5 para manejar las declaraciones de funciones:
Para cada FunctionDeclaration f en el código, en el orden del texto de origen, haga ...
Luego, el paso 8 maneja las declaraciones
var
:
Para cada VariableDeclaration y VariableDeclarationNoIn d en el código, en orden de texto de origen, haga ...
Por lo tanto, las funciones tienen mayor prioridad que las declaraciones
var
, ya que las declaraciones
var
posteriores no pueden sobrescribir una declaración de función manejada previamente.
(El subpaso 8c impone la condición "Si varAlreadyDeclared es falso, entonces [continuar ...]" para que los enlaces de variables existentes no se sobrescriban).
También puedes ver esto experimentalmente :
function f(){}
var f;
console.log(f);
var g;
function g(){}
console.log(g);
Ambas llamadas de
log
muestran la función, no un valor
undefined
.