2010-01-15 19 views
11

Ich bin neu in Javascript und habe verwirrt, wie die Funktionsdeklaration funktioniert. Ich habe einige Test auf, dass und bekam einige interessante Ergebnisse:Mehrdeutige Funktionsdeklaration in Javascript

say(); 

function say() 
{ 
    alert("say"); 
} 

Die Vorwärts-Deklaration gearbeitet und Pop-up „sagen“

Auf der gegenüberliegenden

say(); 

say = function() 
{ 
    alert("say"); 
} 

nicht funktioniert, obwohl es auch deklariert ein Funktionsobjekt

Wenn wir die Funktion deklarieren und später deklarieren:

function say() 
{ 
    alert("speak"); 
} 

say(); 

function say() 
{ 
    alert("say"); 
} 

Ich habe "sagen" statt "sprechen". Das ist Überraschung!

OK. Es scheint, dass nur die letzte Funktionsdeklaration funktioniert. Dann läßt erstes Funktionsobjekt deklariert und dann eine „normale“ Funktion:

say = function() 
{ 
    alert("speak"); 
} 

say(); 

function say() 
{ 
    alert("say"); 
} 

say(); 

Eine weitere Überraschung war es „sprechen“, gefolgt von „sprechen“. Die Deklaration der "regulären" Funktion hat überhaupt nicht funktioniert!

Gibt es eine Erklärung von allen? Und wenn die "normale" Funktionsdeklaration wirklich so "zerbrechlich" ist und leicht vom gleichnamigen Funktionsobjekt überschrieben werden kann, sollte ich davon Abstand halten?

Eine andere Frage ist: mit nur dem Funktionsobjekt-Format, wird diese Vorwärtsdeklaration unmöglich? Gibt es eine Möglichkeit, das in Javascript zu "simulieren"?

Antwort

0

Sie können davon ausgehen, dass Ihre Funktionsdefinitionen der Reihe nach angewendet werden. Dann werden alle nicht-methodischen Codezeilen der Reihe nach ausgeführt, einschließlich der Zuweisung von Funktionsobjekten. Dies erklärt jedes Ihrer Beispiele. Es ist jedoch ein interessantes Thema. Sie können wirklich kein Funktionsobjekt nach versuchen, es aufzurufen, und erwarten, dass es funktioniert. Eine Funktionsdefinition, die auf ausführbaren Code folgt, wird jedoch zuerst angewendet.

3

Javascript funktioniert wie folgt:

Das Dokument analysiert wird und die function Erklärungen sind alle sofort berücksichtigt genommen, vor der Durchführung der eigentlichen Aussagen auftreten. Dies erklärt Ihr erstes Beispiel.

Wenn Sie einer lokalen Variablen eine Funktion zuweisen, die während der Ausführung ausgeführt wird, können Sie die Methode in Ihrem zweiten Beispiel nicht verwenden.

Wenn Sie eine Funktion zweimal deklarieren, wird die letzte von der gesamten Anwendung verwendet. Das ist dein drittes Beispiel.

Diese Funktionen sind Mitglieder des Objekts window, sie werden global deklariert. Wenn Sie einem Wert einer Funktion eine lokale Variable zuweisen, hat diese lokale Variable Vorrang vor Elementen im Objekt window. Wenn JavaScript eine lokale Variable nicht finden kann, sucht es im Bereich nach, um es zu finden, das window Objekt ist der letzte Ausweg. Das ist, was in Ihrem letzten Beispiel passiert ist, es hat eine Variable say, die in einem spezifischeren Bereich als die globale Funktion say ist.

Wenn Sie say zur Laufzeit, also tauschen die Reihenfolge der Anmeldungen in Ihrem letzten Beispiel neu deklarieren würde, dann würden Sie die beiden verschiedenen Warnungen sehen Sie erwarten würden:

say(); //speak, the global function 

function say() { 
    alert('speak'); 
} 

var say = function() { 
    alert('say'); 
} 

say(); //say, the declared local variable 
+0

Ich sehe deine Punkte. Aber was ist der Umfang, wenn ich lokale Funktionsobjekte definiere? Ich versuchte zu rufen window.say() und das Ergebnis ist immer noch nicht, was ich erwartet hatte: function say() { alert("say"); } window.say(); wird Popup „sagen“ und var say = function() { alert("speak"); } window.say(); function say() { alert("say"); } window.say(); wird Popup „sprechen“ zweimal. Bedeutet das, dass sowohl die "globale" Funktion als auch das "lokale" Objekt Mitglieder des Fensterobjekts sind? –

+0

Entschuldigung, ich weiß nicht, wie man den Kommentar formatiert ... :( –

+0

@Xiang: Der Grund, warum Sie zweimal "sprechen", ist, dass der JavaScript-Interpreter zwei Durchgänge durchführt: in der ersten erstellt es Eigenschaften des Objekts Variable (die verwendet wird, um Variablen im aktuellen Bereich nachzuschlagen und ist das globale Objekt im globalen Code) für 'var' Anweisungen und Funktionsdeklarationen, und im zweiten Durchlauf führt sie die Anweisungen der Reihe nach aus. Entscheidend ist, dass 'var' Anweisungen werden effektiv in zwei geteilt: Im ersten Durchgang wird eine Eigenschaft mit dem Wert "undefiniert" zum Variablenobjekt hinzugefügt, wenn sie nicht bereits eine Eigenschaft mit diesem Namen enthält (Fortsetzung ...) –

1
say(); 

function say() 
{ 
    alert("say"); 
} 

Hier die Dolmetscher Fetches die Definition von say(), wenn es aufgerufen wird, und führt es aus.

say(); 

say = function() 
{ 
    alert("say"); 
} 

Hier gibt es keine Definition von say() zu holen - stattdessen werden Sie eine anonyme Funktion einer Variablen zugewiesen. Der Interpreter kann das nicht so finden, als könnte er Vorwärtsdeklarationen finden.

function say() 
{ 
    alert("speak"); 
} 

say(); 

function say() 
{ 
    alert("say"); 
} 

Hier say definiert und dann neu definiert - die letzte Definition siegt.

say = function() 
{ 
    alert("speak"); 
} 

say(); 

function say() 
{ 
    alert("say"); 
} 

say(); 

Hier say ist eine Variable zeigt auf eine anonyme Funktion (nach der ersten Anweisung interpretiert wird). Dies hat Vorrang vor einer Funktionsdefinition, genauso als ob Sie die Funktionsdefinition vor der Zuweisung platziert hätten.

Aber wenn Sie hatte

say(); 

say = function() 
{ 
    alert("speak"); 
} 

say(); 

function say() 
{ 
    alert("say"); 
} 

Dann würden Sie „sagen“ von „sprechen“, gefolgt erhalten.

0

Es ist immer eine gute Idee, die Funktion später aufzurufen, auch wenn JavaScript so funktioniert.

Die meisten Sprachen funktionieren nicht auf diese Weise, sondern tun dies.

function say(){ 
    alert("say"); 
} 

say(); 

oder

say = function(){ 
    alert("say"); 
} 

say(); 

oder

(function(){ 
    alert("say"); 
})();