Verständnis des Verhaltens von Variablen Bei der Umsetzung Rekursion

Verständnis des Verhaltens von Variablen Wenn Umsetzung Rekursion

Problem Sie wollen Rekursion in JavaScript umzusetzen, und Sie wollen auch wissen, wie Variablen werden unter diesen Umständen. Theory In JavaScript, brauchen Sie nicht auf die Variable Art, oder auch die Variable deklarieren erklären verhalten. Zum Beispiel funktioniert der folgende Code perfekt:

if (counter == 1) ( Puffer = "Kontraproduktiv ist 1";) document.getElementById ( "result"). InnerHTML = Puffer;

Der Puffer-Variable wurde nicht erklärt, wenn vor dem Block in der obigen Code. Die letzte Zeile des Codes benutzt den Puffer-Variable auf die Eigenschaft innerHTML zuweisen. Diese Art von Erklärung ist problematisch, weil Puffer sein könnte undefiniert. JavaScript wird nicht erwähnt dies als Fehler und innerHTML zugewiesen wird der Wert nicht definiert. Dieses Beispiel zeigt, dass Variablen in JavaScript in einer Weise, dass ein Programmierer mit Java oder C # Hintergrund kann es nicht gewohnt sein verhalten können. Der Schwerpunkt dieses Rezept ist, herauszufinden, wie eine Variable in verschiedenen Kontexten verhält. Ein Beispiel Zusammenhang ist die Umsetzung der Rekursion in JavaScript. Solution beispielsweise zwei Funktionen, die Rekursion Umsetzung in JavaScript folgen.

 Quelle: / website / ROOT / ajaxrecipes / javascript / variablebehavior.html Funktion RecursionGlobal (Zähler) (info ( "RecursionGlobal (localCounter)", typeof (localCounter)); localCounter = counter; info ( "RecursionGlobal (localCounter)", localCounter), wenn (localCounter <3) (RecursionGlobal (localCounter + 1);)) function RecursionLocal (Zähler) (info ( "RecursionLocal (localCounter)", typeof (localCounter)); var localCounter = counter; info ( "RecursionLocal (localCounter)", localCounter); if (localCounter <3) (RecursionLocal (localCounter + 1);))

Das Beispiel zeigt zwei Methoden: RecursionGlobal und RecursionLocal. Zwischen den beiden Methoden gibt es einen einzigen Unterschied, wie in den kühnen Code dargestellt: Die JavaScript-Schlüsselwort var. Die einzigen Schlüsselwort var ist die Variante, wie die localCounter Variablen gespeichert ist. Das Verhalten der beiden Methoden bei der Ausführung identisch ist und erzeugt das gleiche Ergebnis. Sie können auf den ersten Blick denken, dass das Schlüsselwort var keinen Zweck. Aber das Schlüsselwort var nicht einem Zweck dienen, die mit dem folgenden Programm dargestellt ist:

Info: recursion_global Started *** *** Info: RecursionGlobal () localCounter undefined Info: RecursionGlobal (1) localCounter Info: RecursionGlobal () localCounter Anzahl Info: RecursionGlobal (2) localCounter Info: RecursionGlobal () localCounter Anzahl Info: RecursionGlobal (localCounter 3) Info: recursion_local Started *** *** Info: RecursionLocal () localCounter undefined Info: RecursionLocal (1) localCounter Info: RecursionLocal () localCounter undefined Info: RecursionLocal (2) localCounter Info: RecursionLocal () localCounter undefined Info: RecursionLocal localCounter () 3
  

Beachten Sie, dass, wenn die RecursionGlobal Funktion, führt den Typ des localCounter für den ersten Aufruf nicht definiert ist, und danach ist es ein. Im Gegensatz dazu, wenn die RecurisonLocal Funktion aufgerufen wird, die Art der localCounter ist für jeden Aufruf undefiniert.

Dies bedeutet, dass var Zweck der Erklärung dient eine Variable, die den Umfang von dem sie deklariert ist lokaler ist. Wenn die Variable nicht mit einem Schlüsselwort var verbunden sind, dann wird die Variable im globalen Bereich erklärt. Im Falle der Schaffung einer Rekursion Schleife, müssen Sie das Schlüsselwort var für alle Fälle verwenden, sonst könnte es zu Datenverlust führen. Das folgende Beispiel zeigt, wie der Inhalt eines Stapels Rekursion umzukehren. Bei der Verwendung von Rekursion, manchmal müssen die Parameter der Funktion zu erklären, dass keine anderen Zweck als Referenzwerte dienen.

 Quelle: / website / ROOT / ajaxrecipes / javascript / variablebehavior.html Funktion RecursiveStackOldWay (arrayToProcess, processedArray) (info ( "RecursiveStackOldWay", "---> Start "); info (" RecursiveStackOldWay "," Rekursive Tiefe = "+ (processedArray. Länge + 1)); processedArray.push (arrayToProcess.pop ()); if (arrayToProcess.length> 0) (RecursiveStackOldWay (arrayToProcess, processedArray);) info ( "RecursiveStackOldWay", "---> End ");) var arrayToProcess = new Array (); arrayToProcess.push ( "Wert1"); arrayToProcess.push ( "Wert2"); var processedArray = new Array () RecursiveOldWayStack (arrayToProcess, processedArray);

Hier hat die RecursiveStackOldWay Funktion zwei Parameter: arrayToProcess und processedArray. Der erste Parameter, arrayToProcess, wird das Array, dass umgekehrt werden. Der zweite Parameter, processedArray, ist das Ziel-Stack. Die Ziel-Stack muss als Parameter für jede Rekursion mitgeschleppt, so dass die Funktion legte den Stapel irgendwo können. Der Anrufer wird zum Erzeugen von Stack und das Ziel, sie an die rekursive Funktion verantwortlich. Aber in vielen Fällen bei der Erstellung von rekursiven Funktionen , müssen Sie die Funktion mit bestimmten Parametern, die in die erste Top-Level definiert sind telefonisch erreichen können. Diese Parameter haben nichts mit dem ersten Aufruf zu tun, doch die erste Top-Level-Aufruf muss sie erklären (processedArray). Kurz gesagt, ist das Problem, wenn Sie eine rekursive Funktion, müssen Sie eine Reihe von Variablen, die dann durch die Rekursion verwendet werden, zu initialisieren. Im Beispiel wird die Initialisierung in der Verantwortung des Anrufers. Die Lösung funktioniert, aber es ist bei weitem nicht optimal, da die Entwickler muss verstehen, wie bestimmte Parameter, Funktion, auch wenn sie nicht von dem Anrufer verwendet werden. Eine weitere Lösung ist eine Wrapper-Funktion, um die Rekursion, dass die Parameter initialisiert und ruft dann die Rekursion zu schaffen.

Die Wrapper-Funktion funktioniert, aber jetzt hat der Programmierer, um die Rekursion Funktion und die Wrapper-Funktion zu erhalten. JavaScript bietet eine dritte Lösung: Lassen Sie die Rekursion Funktion selbst zu initialisieren. Die Frage ist, wie funktioniert die Rekursion Funktion weiß, es ist zum ersten Mal aufgerufen wird? In einer traditionellen Programmiersprachen wie Java oder C #, würde einen booleschen Parameter definiert werden und auf true, um den ersten Aufruf angegeben gesetzt, und falsch, daß jede spätere Aufforderung anzugeben. Die JavaScript-Lösung erfordert nicht eine Flagge oder ein Indikator, da die Parameter selbst Indikatoren. Stellen Sie sich beispielsweise, wenn die Funktion RecursiveOldWayStack Umsetzung bleibt wie sie ist und der Code, der RecursiveOldWayStack ungefähr wie folgt aussieht:

var arrayToProcess = new Array (); arrayToProcess.push ( "Wert1"); arrayToProcess.push ( "Wert2"); var processedArray = RecursiveOldWayStack (arrayToProcess);

In der modifizierten Umsetzung der Anrufer ist nicht verantwortlich für die Instanziierung Ziel-Stack. Diese Zuständigkeit wurde der RecursiveOldWayStack Funktion übertragen. Es stellt sich jedoch ein Problem, weil RecursiveOldWayStack Bedürfnisse zu initialisieren und die Rekursion zu beginnen. Die Lösung von JavaScript verwendet wird, um festzustellen, ob der zweite Parameter definiert ist, wie in der folgenden veränderten Funktion namens RecursiveStack dargestellt.

 Quelle: / website / ROOT / ajaxrecipes / javascript / variablebehavior.html Funktion RecursiveStack (arrayToProcess, processedArray) (info ( "RecursiveStack", "---> Start "); if (typeof (processedArray) == "undefined") ( info ( "RecursiveStack", "Erste"); processedArray = new Array (); RecursiveStack (arrayToProcess, processedArray); info ( "RecursiveStack", "---> End "); Rückkehr processedArray; )else (info ( "RecursiveStack", "Rekursive Tiefe =" + (processedArray.length + 1)); processedArray.push (arrayToProcess.pop ()); if (arrayToProcess.length> 0) (RecursiveStack (arrayToProcess, processedArray); ) info ( "RecursiveStack", "---> End "); return;))

In der modifizierten Umsetzung setzt die RecursiveStack Funktion eine Erwartung. Die Erwartung ist, dass, wenn die Funktion mit einem einzelnen Parameter aufgerufen wird, dann ist es ein Anrufer dabei der erste Aufruf der Rekursion, andernfalls ist eine Rekursion geschieht. Die Erwartung, zu wissen, ob eine erste passiert ist, ist der Code in Fettdruck bestimmt. Wenn der zweite Parameter, processedArray, ist nicht definiert, dann ist die rekursive Funktion initialisiert sich und startet die Rekursion. Wenn der zweite Parameter definiert ist, dann wird davon ausgegangen, eine Rekursion ist im Gange, und die Funktion werden die Daten als solche. Bevor wir weitermachen, könnten Sie die Tatsache, dass RecursiveStack hat zwei Parameter Prozess gefangen haben, wird aber mit einem Namen.

Früher habe ich gesprochen und über die Erwartungen, dass der Anrufer muss zwei Parameter übergeben. Dieses Beispiel kann nicht sagen, dass der Anrufer keine Notwendigkeit, zwei Parameter übergeben, sondern sagt, das Beispiel, dass, wenn der Anrufer nicht passieren zwei Parameter, hat die Funktion, die Fähigkeit zu kompensieren. Die gleiche Funktion kann für die Initialisierung und verwendet werden Rekursion basiert auf der Erwartung. Ist aber bestimmt ein Anrufer die zweite Parameter, dass der Anrufer hat die Verantwortung übernommen, um die Initialisierung durchzuführen bedeutet. Mit einem Anrufer definierte Initialisierung, wird RecursiveStack eine Initialisierung nicht durchführen und wird direkt zu der Rekursion Funktionalität.

Der Vorteil dieser Lösung ist, dass Sie ein Mehrzweck-Funktion haben, ohne ausdrücklich eine Wrapper-Funktion zu definieren. Sie können sich denken: "Natürlich ist dies möglich mit einer Sprache wie Java oder C # mit überladenen Funktionen." Ja, es ist möglich mit überladenen Funktionen, aber wie bereits erwähnt, ist eine überladene Funktion eine Wrapper-Funktion, dass die tatsächliche Umsetzung verlangt , also zwei Funktionen geschrieben werden müssen und gewartet werden. In JavaScript können, alles in einem getrennt Funktion gewickelt werden. Nun, da Sie Rekursion implementiert und kennen den Unterschied zwischen einer lokal gültigen Variablen und einer global Gültigkeitsbereich Variable, die nächste Frage ist, was passiert, wenn zwei Variablen sind mit den gleichen Namen? Stellen Sie sich vor der Definition einer Variable in einem lokalen Bereich, der in einem globalen Rahmen, was zu den global und lokal gültigen Variablendeklarationen passiert, gibt es? Der folgende Code zeigt, wie eine Variable global in einer Funktion definiert wird und dann in einer anderen Funktion verwiesen wird.

 Quelle: / website / ROOT / ajaxrecipes / javascript / variablebehavior.html Funktion GlobalScope () (info ( "GlobalScope scopedVariable ()", typeof (scopedVariable)); scopedVariable = "GlobalScope"; info ( "GlobalScope scopedVariable ()", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable));) function testScope () (info ( "OtherScope (scopedVariable)", "scopedVariable = "+ scopedVariable + "Type =" ➥ + typeof (scopedVariable));)

scopedVariable in GlobalScope definiert und in testScope verwiesen wird. Da es keine var-basierte Erklärung der scopedVariable in GlobalScope ist scopedVariable in den globalen Rahmen gesetzt. Running testScope nach GlobalScope in scopedVariable führen, dass global definiert, wie in der folgenden generierte Ausgabe angezeigt:

Info: GlobalScope scopedVariable () undefined Info: GlobalToLocalScope () scopedVariable GlobalScope scopedVariable = type = string Info: testScope scopedVariable () = scopedVariable GlobalScope type = string

In den generierten Output, ist GlobalScope genannt wird, und zu Beginn des Funktions-Implementation, scopedVariable ist nicht definiert. Dann scopedVariable zugeordnet ist ein Puffer, und die erzeugte Ausgabe zeigt, dass scopedVariable ist nicht definiert und verweist auf eine Zeichenfolge. Calling testScope zeigt, dass scopedVariable global ist und erhält einen Puffer. Betrachten wir nun das gleiche Beispiel, nur ein global Gültigkeitsbereich Variable wird als neu vereinbart lokale Variable mit dem Schlüsselwort var.

 Quelle: / website / ROOT / ajaxrecipes / javascript / variablebehavior.html Funktion AlwaysLocalScope () (info ( "GlobalToLocalScope (scopedVariable)", typeof (scopedVariable)); scopedVariable = "AlwaysLocalScope"; info ( "GlobalToLocalScope (scopedVariable)", "scopedVariable = "+ + scopedVariable ➥" type = "+ typeof (scopedVariable)); var scopedVariable;)

In der Funktions-Implementation wird scopedVariable ersten Einsatz einen Puffer, die nicht das Schlüsselwort var Verwendung führt. So ist scopedVariable auf globaler Ebene Umfang erklärt. Oder zumindest das ist, was Sie führte zu glauben. Was passiert, ist, dass die Variable auf der lokalen Ebene erklärt wird, weil die letzte Anweisung der Funktion (in Fettdruck) die scopedVariable Variable deklariert werden lokal. Es mag seltsam erscheinen, dass eine Variable deklariert wird, um eine lokale, wenn irgendwo in der Funktion der var Stichwort verwendet wird. Es wird noch seltsamer, daß, wenn das Schlüsselwort var in eine Entscheidung blockieren, die nie ausgeführt wird, verwendet wird, ist die Variable noch erklärt local. Um zu veranschaulichen, werden zunächst die AlwaysLocal Funktion wird aufgerufen, und dann testScope, die die folgende Ausgabe erzeugt:

Info: AlwaysLocalScope () scopedVariable undefined Info: AlwaysLocalScope (scopedVariable) scopedVariable = AlwaysLocalScope type = string Warn: Allgemeiner Fehler (scopedVariable ist nicht definiert)

Wenn die AlwaysLocalScope Funktion aufgerufen wird, wird scopedVariable nicht definiert, dh es existiert weder globale noch von den örtlichen Geltungsbereich. Dann, wenn die Variable zugewiesen wird, wird die generierte Ausgabe einen Wert haben und geben. Wenn die testScope Funktion aufgerufen wird, wird eine Ausnahme ausgelöst, weil scopedVariable nicht definiert ist. Jetzt wissen Sie, wenn eine Variable im globalen Gültigkeitsbereich deklariert und in den lokalen Bereich. Der letzte Test ist zu sehen, was passiert, wenn eine Variable im globalen wie im lokalen Bereich angemeldet wird. Der Test beinhaltet den Aufruf der Funktionen in der Reihenfolge: GlobalScope, testScope, AlwaysLocalScope und dann testScope. Der Aufruf dieser Sequenz erzeugt die folgende Ausgabe:

Info: GlobalScope scopedVariable () undefined Info: GlobalScope scopedVariable () = scopedVariable GlobalScope type = string Info: testScope scopedVariable () = scopedVariable GlobalScope type = string Info: AlwaysLocalScope () scopedVariable undefined Info: AlwaysLocalScope (scopedVariable) scopedVariable = AlwaysLocalScope type = string Info: testScope scopedVariable () = scopedVariable GlobalScope type = string

In den generierten Output, ist scopedVariable deklariert und in GlobalScope zugeordnet. Die Funktion überprüft, ob testScope scopedVariable existiert. Dann, wenn AlwaysLocalScope Beruf, erklärt, var, dass jede Bezugnahme auf scopedVariable innerhalb der Funktion eine lokale Variable verwiesen wird. So, wenn es eine global definierte Variable mit dem gleichen Namen, und ist nicht zugänglich in den Anwendungsbereich der Funktion. Sie haben zwei Möglichkeiten, auf eine globale Variable: Referenzierung über das Fenster-Eigenschaft oder die Erstellung einer Funktion, die die ausgeführte Funktion ist externe (dh es ist nicht eine Inline-Funktion) und die Zuordnung der globalen Gültigkeitsbereich Variable. Wenn eine Variable nicht zugewiesen ist, die typeof Funktion gibt nicht definiert.

Wenn Sie eine Variable, wird typeof Rückkehr einen anderen Wert. Wenn eine Variable ist im Zusammenhang mit einer Funktion definiert, dann jedes Mal die Funktion aufgerufen wird, wird die Variable, bevor sie zugeordnet sind undefiniert. Auf globaler Ebene kann eine Variable mit dem Operator delete nicht gesetzt werden, wie folgt: scopedVariable löschen, in der Regel der Betreiber löschen, wird verwendet, um die Eigenschaft eines Objekts zurückgesetzt. Wenn löschen, wird eine Kennung, eine globale Variable Referenz verwendet wird gestrichen. Sie können nicht entfernen Sie einen Verweis auf eine Funktion mit zu löschen. Let's Test eine weitere Variante des Anwendungsbereichs mit dynamischen Code. In JavaScript wird mit Hilfe der eval-Funktion führen Sie einen JavaScript-Puffer, der Prüfungen, wenn eine Variable globalen Bereich angesehen werden und wann sie als lokalen Bereich. Die AlwaysLocalScope Funktion wird entsprechend geändert. Für die erste Variante, wird AlwaysLocalScope haben eine dynamische Zuordnung:

Funktion AlwaysLocalScope () (info ( "AlwaysLocalScope (scopedVariable)", typeof (scopedVariable)); eval ( "scopedVariable = 'AlwaysLocalScope'");info ( "AlwaysLocalScope (scopedVariable)", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable)); var scopedVariable;)

Der geänderte Code ist fett gedruckt, und die Zuweisung der scopedVariable ausgeführt wird. Mit eval auf diese Weise hat keine Wirkung, und die dynamische Ausführung des Codes ist die gleiche wie wenn der Code nicht geändert wurde. Der Vorteil mit eval ist, dass Sie ein Stück Code, um einen Text Puffer zuweisen können, und führen Sie dann die Puffer. Der Umfang der scopedVariable wurde nicht geändert, weil das Schlüsselwort var immer noch in der Funktion Erklärung an. Die Erklärung, wenn sie von der JavaScript-Prozessor geparst werden in eine lokale Variable Erklärung führen. Eine Möglichkeit, die lokale Deklaration Verhalten zu ändern ist, die Deklaration von Variablen in ein eval-Anweisung einbinden, wie in den folgenden Code Änderung angezeigt:

Funktion AlwaysLocalScope () (info ( "AlwaysLocalScope (scopedVariable)", typeof (scopedVariable)); eval ( "scopedVariable = 'AlwaysLocalScope'");info ( "AlwaysLocalScope (scopedVariable)", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable)); eval ( "var scopedVariable;");)

Der geänderte Code mit Bezug auf die ursprüngliche AlwaysLocalScope Code ist fett. Diese Zeit, sowohl die Zuordnung und die Erklärung der scopedVariable sind dynamisch, was bedeutet, dass, wenn scopedVariable zugewiesen wird als globale Variable behandelt werden. Dies liegt daran, wenn der erste eval-Anweisung ausgeführt wird, gibt es keine Erklärung scopedVariable, und der JavaScript-Laufzeit wird scopedVariable im globalen Raum zu speichern. Um das Verhalten zu ändern und zu erklären scopedVariable als lokale Variable, AlwaysLocalScope muss geändert werden, ein weiteres Mal , wie folgt:

Funktion AlwaysLocalScope () (info ( "AlwaysLocalScope (scopedVariable)", typeof (scopedVariable)); eval ( "var scopedVariable;"); eval ( "scopedVariable = 'AlwaysLocalScope'");info ( "AlwaysLocalScope (scopedVariable)", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable));)

In der letzten Änderung, ist der erste eval die Erklärung der scopedVariable mit dem Schlüsselwort var. Der erste Anruf eval Ergebnisse in der Erklärung von scopedVariable als lokale Variable. Der zweite Anruf eval ein Wert zugewiesen scopedVariable, die als lokale Variable Gültigkeitsbereich ist. Bei der Deklaration von Variablen im Rahmen der Funktionen oder im globalen Rahmen, halten Sie die folgenden Punkte beachten:

• Es gibt zwei Bereiche, eine Variable: lokal zu einer Funktion und global.

• Eine lokale Variable deklariert wird mit dem Schlüsselwort var, mit der Ausnahme der Verwendung von var in einem globalen Kontext. Die Verwendung von VaR muss nicht am Anfang einer Funktion.

• Eine globale Variable deklariert ist, wenn eine Variable ohne das Schlüsselwort var zugeordnet ist.

• Es ist gute Praxis, Variablen, die auf globaler Ebene zu erklären Umfang mit dem Schlüsselwort var.

• Lokale und globale Variablen mit dem gleichen Namen überschreiben sich nicht gegenseitig. Ein lokal deklarierte Variable verbirgt sich ein global deklarierten Variable mit dem gleichen Namen.

• Wenn eine Variable nicht angegeben, mit typeof auf die Variable, führt zu undefiniertem.

• Sie können Einfluss auf die globale Variablen mit dem Operator delete.

• Bei rekursiven Funktionen verwenden, sollten Sie lokal deklarierte Variablen.

• Rekursion umfasst in der Regel eine Initialisierung und einer Hinrichtung. Mit Hilfe von JavaScript, die Initialisierung und Durchführung kann in einer einzigen Funktion gewickelt werden.

• Geschenkpapier Initialisierung und Ausführung in einer einzigen Funktion verwendet Erwartungen, denen die Verfügbarkeit der Variablen wird geprüft, um eine Berufung Kontext zu bestimmen.

• Es ist möglich, eval dynamisch zu lokalen oder globalen Variablen zu deklarieren.

• Mit eval Ursachen der JavaScript-Prozessor nicht automatisch einen Look-Ahead bei der Identifizierung lokalen Variablen. So, auf eine lokale Variable zu deklarieren, müssen das Schlüsselwort var vor der Zuweisung einer Variablen verwendet werden.

• Mit der eval-Anweisung, könnte ein Programm dynamisch ermitteln, ob eine Variable bei den lokalen Bereich oder im globalen Rahmen zu erfolgen hat.

Ein Artikel eingereicht von Sonja Lande


Disclaimer:Unsere Website ist nicht verantwortlich für den Inhalt dieses Artikels. Webarticles ist eine kostenlose Informationsquelle.
Wichtig: Dieser Artikel "Das Verständnis des Verhaltens von Variablen Bei der Umsetzung Rekursion" wurde durch ein automatisches Software übersetzt. Wir fühlen uns leid für alle Rechtschreibfehler, die möglicherweise aufgetreten sind. Vielen Dank für Ihr Verständnis.


Online: 292 users browsing the articles directory