J'ai écrit le script suivant juste pour voir ce qui se passe lorsqu'une variable et une fonction à laquelle une fonction est assignée ont leur nom en conflit:
var f = function() {
console.log("Me original.");
}
function f() {
console.log("Me duplicate.");
}
f();
Le résultat que j'obtiens est "Moi original". Pourquoi l'autre fonction n'a-t-elle pas été appelée?
De plus, si je change mon affectation d'origine en var f = new function() {
, j'obtiens "Moi original", suivi d'un message TypeError object is not a function
. Quelqu'un peut-il expliquer?
javascript
function
ankush981
la source
la source
Réponses:
Les déclarations de fonction sont hissées (déplacées vers le haut) en JavaScript. Bien qu'il soit incorrect en termes d'ordre d'analyse, le code que vous avez est sémantiquement le même que le suivant puisque les déclarations de fonction sont levées:
Ce qui à son tour, à l'exception du nom de la fonction, est le même que:
Ce qui à son tour, en raison du levage variable, est le même que:
Ce qui explique ce que vous obtenez, vous remplacez la fonction. Plus généralement, plusieurs
var
déclarations sont autorisées en JavaScript -var x = 3; var x = 5
c'est parfaitement légal. Dans la nouvelle norme ECMAScript 6, leslet
déclarations l'interdisent.Cet article de @kangax fait un travail fantastique dans la démystification des fonctions en javascript
la source
function f()
àvar f = function()
ce point? Les noms de levage et de fonction sont-ils vraiment la seule différence?f
sont hissées, et la"Me Original"
version est simplement hissée plus tard , elles sont chacune déplacées vers le haut mais dans le même ordre. Je voudrais juste ajouter qu'en général, il ne faut pas nommer plusieurs fonctions de la même manière :)var
le même nom deux fois dans la même portée.Si personne ne semble avoir répondu à votre question de suivi, je vais donc y répondre ici, mais vous devriez généralement poser des questions de suivi sous forme de questions distinctes.
Vous avez demandé pourquoi ceci:
imprime «Moi original». puis une erreur.
Ce qui se passe ici, c'est que la
new
fonction est utilisée comme constructeur. Cela équivaut donc à ce qui suit:Et grâce à la fonction de levage expliquée par Benjamin, ce qui précède est essentiellement équivalent à ceci:
Cette expression:
provoque la construction et l'affectation d'un nouvel objet
f
, en utilisant une fonction anonyme comme constructeur. "Moi original." est imprimé lors de l'exécution du constructeur. Mais l'objet qui est construit n'est pas lui-même une fonction, donc quand cela s'exécute finalement:vous obtenez une erreur, car ce
f
n'est pas une fonction.la source
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:La sortie sera alors:
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:
* 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.
la source