2016-04-25 6 views
1

An alle JS-Experten, Im immer noch versuchen, JS mit Bücher aus Stoyan Stefanov (Object-Oriented JS) zu lernen.JS - Verwirrung über die Funktion, die sich selbst umschreiben

Lassen Sie sich auf Seite 83 stecken, wo die folgenden Codes müssen, dass

Das Buch vorgeschlagen

a = a(); // First Call 
 
function a() { 
 
alert('A'); 
 
a = function() { // I get this. Redefining functions. 
 
    alert('B'); 
 
}; 
 
} 
 
a(); // Second Call
arbeiten, wenn wir Anruf/zum 2. Mal aufrufen würde es tatsächlich Alarm B nach Alarm A auftreten.

jedoch, anstatt zu arbeiten es uns Typeerror gibt: a ist keine Funktion nach erfolgter Benachrichtigung A.

Was ist die hier Fehler ??

Danke

Antwort

2

Die erste Zeile:

a = a(); 

ruft die Funktion und weist den Rückgabewert zu a. Aber der Rückgabewert der Funktion ist undefined - jede Funktion, die nicht explizit einen Wert mit return zurückgibt, gibt implizit undefined zurück (sofern nicht mit new aufgerufen, aber Sie können das hier ignorieren). Also dann in der letzten Zeile, wenn Sie sagen a() Sie sagen im Grunde undefined(). Und natürlich ist undefined keine Funktion.

Hat der Code im Buch wirklich a = a();? Ändern Sie es in a() und es wird wie erwartet funktionieren.

Alternativ können Sie die Funktion ändern, um die neue Funktion auf dem ersten Gespräch zurückzukehren, anstatt a direkt überschreiben:

a = a(); // First Call 
function a() { 
alert('A'); 
// following line changed to return the new function instead 
// of assigning it to a immediately 
return function() { 
    alert('B'); 
}; 
} 
a(); // Second Call 
+0

so die richtige Sache sollte 'Return-Funktion sein() {alert ('B')}' davon statt. Also Fehler aus den Büchern ?? – xcode

+0

Ja, das Zurückgeben der Funktion würde mit 'a = a()' funktionieren. Ich füge das meiner Antwort hinzu. – nnnnnn

+0

Danke. Sehr klare und hilfreiche Antwort – xcode

0

Wenn Sie das tun einen ersten Anruf

a = a(); // First Call 

Sie Funktion Ergebnis zuweisen Ihre Variable a. Doch Ihr a() gibt nichts zurück. Also, bei einem zweiten Versuch ist ein undefined.

Das Ändern der ersten Zeile auf nur a() behebt es.

0

Dieses Beispiel zeigt, wie die Benennung von Variablen und Funktionen und deren Umfang in JavaScript wichtig ist. Betrachten Sie den folgenden Code ...

Also, was ist los?

Die innere Variable a der function a() gibt seine Art: function

Die globale Variable a auf den Rückgabewert von function a() eingestellt ist - aber die Funktion nicht alles zurückgeben, damit es undefined

automatisch wird Die Art der globalen function a() ist immer noch durch den Wert a 'außerhalb' von sich selbst bestimmt (sozusagen) - undefined

N Oder die Reihenfolge, in der die Anrufe an console.log() ankommen?

Nicht nur die inneren a nicht mit var eingestellt, automatisch im globalen Bereich platzieren, aber a = a() bedeutet es nicht einmal mehr eine Funktion!

Es ist a = a(), die a is not a function TypeError verursacht.

Auf der anderen Seite, schauen, was passiert, wenn ich a = entfernen, aber alles andere lassen, wie es ...

war
a(); 
console.log('typeof global variable a :',(typeof a)); 
function a() { 
    console.log('A'); 
    a = function() { 
     console.log('B'); 
    }; 
    console.log('typeof global function a() inner function a() :',(typeof a)); 
} 
console.log('typeof global function a() :',(typeof a)); 
a(); 

//=> A 
//=> typeof global function a() inner function a() : function 
//=> typeof global function a() : function 
//=> typeof global variable a : function 
//=> B 

Sehen Sie, wie die Reihenfolge geändert hat?

Wir können jetzt nicht an 'globale Variable a' (wie zuvor) als Variable denken - die a ist nur ein Token, das auf die Funktion zeigt.

function a() genannt wird, löst das console.log( A ), setzt die Token a (die selbst ist) an die neue Funktion, und dann löst das console.log( B ) wenn erneut aufgerufen.

Es gibt ein bisschen mehr Details, die herausgefiltert werden können, und bessere Möglichkeiten, um das gleiche Ergebnis zu erzielen, aber die Aufrufe an die Konsole sind ein großer Hinweis auf das, was vor sich geht. Stellen Sie sich das Beispiel nicht als brauchbares Muster vor, sondern betrachten Sie es als etwas, das darauf hinweist, wie eine JavaScript-Engine das tut, was sie tut.

Sie können diesen Artikel von JavaScriptIsSexy.com nützlich finden: JavaScript Variable Scope and Hoisting Explained

+0

Danke für Ihre Hilfe. Nebenbei erwähnen Sie über verwendbare Muster, gute Bücher, die Sie empfehlen, um das neueste Muster für Javascript-Anwendung zu lernen? – xcode

Verwandte Themen