Pardonnez-moi si ce n'est pas la bonne façon d'aborder l'ajout d'un point. Je n'ai pas beaucoup été ici et j'accepterais une direction constructive et / ou des critiques.
La réponse de Benjamin répond parfaitement à la question du PO, mais j'aimerais ajouter une modification qui nous donnera un tour complet du levage et de ses bizarreries.
Si nous commençons le code d'origine par un appel à f
, comme ceci:
f();
var f = function() {
console.log("Me original.");
};
function f() {
console.log("Me duplicate.");
}
f();
La sortie sera alors:
Me duplicate.
Me original.
La raison étant que var
etfunction
déclarations sont soulevées de manière légèrement différente.
Pour var
la déclaration est déplacée en haut de la portée actuelle *, mais toute affectation n'est levée. En ce qui concerne la valeur de la variable déclarée, elle n'est pas définie tant que la ligne d'affectation d'origine n'est pas atteinte.
Pour function
déclarations , la déclaration et la définition sont hissées. Expressions de fonction , telles qu'utilisées dansvar f = function() {...
construction, ne sont pas hissées.
Donc, après le levage, l'exécution est comme si le code était:
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();
* Toute la portée JavaScript est lexicale, ou fonction, portée, mais il semblait que cela ne ferait que confondre les choses pour utiliser le mot f à ce stade.