Perdóname si esta es la forma incorrecta de abordar la adición de un punto. No he estado mucho por aquí y agradecería una dirección constructiva y / o críticas.
La respuesta de Benjamin aborda la pregunta del OP de manera excelente, pero me gustaría agregar un ajuste que nos dará un recorrido completo por el izado y sus rarezas.
Si comenzamos el código original con una llamada a f
, así:
f();
var f = function() {
console.log("Me original.");
};
function f() {
console.log("Me duplicate.");
}
f();
La salida será entonces:
Me duplicate.
Me original.
La razón es que las declaraciones var
y function
se expresan de maneras ligeramente diferentes.
Porque var
la declaración se mueve a la parte superior del alcance actual *, pero no se eleva ninguna asignación . En lo que respecta al valor de la var declarada, no está definido hasta que se alcanza la línea de asignación original.
Para las function
declaraciones , se incluyen tanto la declaración como la definición. Las expresiones de función , tal como se utilizan en la var f = function() {...
construcción, no se elevan.
Entonces, después de izar, la ejecución es como si el código fuera:
var f; // declares var f, but does not assign it.
// name and define function f, shadowing the variable
function f() {
console.log("Me duplicate.");
}
// call the currently defined function f
f();
// assigns the result of a function expression to the var f,
// which shadows the hoisted function definition once past this point lexically
f = function() {
console.log("Me original.");
}
// calls the function referenced by the var f
f();
* Todo el alcance de JavaScript es léxico, o de función, pero parece que confundir las cosas con usar la palabra f en ese punto.