Funktion
Funktionsformat
Funktion getPrototynames (o,/*optional*/ a) {a = a || []; für (var p in o) {a.push (p);} return a;}Anrufer
func.caller gibt den Funktionsanrufer zurück
Funktion callfunc () {if (callfunc.caller) {alert (callfunc.caller.toString ());} else {alert ("no function Call");}} Funktion HandleCaller () {callFunc ();} HandleCaller (); // return handlercallFunc ();Callee
Anonyme Methode rekursiver Anruf
alert ((Funktion (x) {if (x <=) return; return x * argumente.callee (x -);} ())); //Umfang
Jeder ist mit dem Umfang vertraut. Heute werde ich über das Schließungsproblem sprechen und das Schließungsproblem gründlich verstehen.
<Script> var Global = "Global Scope"; // Dies ist der Global Scope Function Scope () {var scope = "Lokaler Bereich"; // Dies ist der lokale Umfang der Rendite, // Das zurückgegebene Umfang ist eine lokale Variable} </script>1.: Die definierten globalen Variablen können auch innerhalb der Funktion zugegriffen werden . Wenn der definierte lokale Variable- und globale variable Name gleich ist, verbergt die lokale Variable die globale Variable und zerstört den Wert der globalen Variablen nicht.
var Scope = "Global Scope"; Funktion f () {var scope = "Lokaler Bereich"; Return Scope;} alert (f ()); // lokaler Scopealt (Scope); // globaler Umfang;Das obige ist in der Tat leicht zu verstehen, oder?
2. Globale Variablen können ohne VAR deklariert werden , aber lokale Variablen müssen mit VAR deklariert werden. Wenn lokale Variablen keine VAR -Deklaration verwenden, wird der Compiler dies als globale Variable standardmäßig.
<span style = "line-height :.; Schriftfamilie: Verdana, Arial, Helvetica, Sans-Serif; Schriftgröße: px; Hintergrundfarbe: rgb (,);"> </span> scope = "global scope";
Globale Variablen verwenden jedoch keine VAR-Deklarationen und sind nur für den Nichtstreifenmodus verfügbar. Wenn ein strenger Modus verwendet wird, wird ein Fehler gemeldet.
<Script> "Verwenden Sie Strict"; Scope = "Global Scope"; Funktion f () {scope = "Lokaler Bereich"; Return Scope;} alert (f ()); // lokaler Scopealt (Scope); // Lokaler Bereich </script>Daher wird empfohlen, dass Sie VAR bei der Deklarierung von Variablen nicht weglassen, da dies unnötige Probleme vermeiden kann.
3. Es ist in Ordnung, im Voraus zu deklarieren . Was ist was ist im Voraus?
<Script> "Strict"; Scope; Console.log (Scope); var scope = "global scope"; console.log (scope); </script>
Dies kann als der erste gesehen werden, der undefinierte Drucken angesehen werden kann. Ja, es wurde noch kein Wert zugewiesen. Die folgende Zuordnung kann den globalen Bereich bestimmen.
Das ist nicht falsch, aber warum passiert das? Sollte eine Variable nicht definiert werden, bevor sie verwendet werden kann?
Hier werde ich Ihnen von der Scope -Kette erzählen. JavaScript ist eine lexikalische Scoped -Sprache.
1. Eine Scope -Kette ist ein Objekt oder eine verknüpfte Liste. Dieser Codesatz definiert die Variablen "im Bereich" dieses Code ". Wenn JavaScript den variablen Bereich ermitteln muss, entwickelt es und sucht vom ersten Objekt in der Kette. Wenn das erste Objekt umfangreich ist, wird der Wert dieses Objekts direkt zurückgegeben. Wenn es nicht existiert, sucht es weiterhin das zweite Objekt, bis es gefunden wird. Wenn die Variable nicht in der Bereichskette gefunden wird, wird ein Fehler geworfen.
Wir können diese Funktionskette wie folgt ausdrücken: Suchen Sie das Fenster "Zielfernrohr" (globales Objekt) und dann wird der Umfang definiert. Die Zuordnungsoperation wurde jedoch nicht durchgeführt, und die Zuordnungsoperation wurde später durchgeführt, sodass der Wert zu diesem Zeitpunkt undefiniert ist.
4. Das ist verwirrender. Was ist der gedruckte Wert?
<Script> "Strict"; var scope = "global scope"; Funktion f () {console.log (scope); var scope = "local scope"; console.log (scope);} f (); </script>Siehe diesen Code: Wenn Sie nachlässig sind, können Sie die falsche Antwort schreiben:
1. GOBAL SCOPE
2. Lokaler Bereich
Analyse: Deklarieren Sie globale Variablen. Wenn in der Funktionsbehörde die erste globale Variable darstellt, wird global gedruckt, und der zweite definiert lokale Variablen, die den globalen Bereich abdecken, sodass lokaler Bereich gedruckt wird.
Eine solche Analyse ist in C# Java vollständig korrekt. Aber die Analyse hier ist in der Tat falsch.
Dies zeigt, dass vor diesem Problem uns zuerst eine Frage betrachten.
Dieser Satz ist sehr wichtig: Globale Variablen sind im Programm immer definiert. Lokale Variablen sind immer im Körper der Funktion definiert, die sie deklariert, und die Funktionen, die es nester macht.
Wenn Sie in einer hochrangigen Sprache arbeiten, werden Sie JavaScript ausgesetzt, die für seine Bereichsdefinition ein wenig ungeeignet sind. Ich bin genauso. Schauen wir uns ein Beispiel an:
<Script> var g = "Global Scope"; Funktion f () {für (var i =; i <; i ++) {für (var j =; j <; j ++) {;} console.log (j);} console.log (i);} console.log (g); f ();Was ist das Ergebnis des Druckens?
Sie sehen, dass {} einen Anweisungsblock darstellt und der Anweisungsblock im Bereich desselben Blocks liegt. Sie können also vermuten, dass die J- und I -Werte im Speicher freigegeben wurden, sodass das Ergebnis nicht definiert werden muss.
Das eigentliche Ergebnis kann Sie enttäuschen.
Warum ist das passiert? Mein Ausdruck begann wie du.
Schauen Sie sich den Satz an, den ich Ihnen gebeten habe, sich jetzt zu erinnern. . . Globale Variablen sind im Programm immer definiert. Lokale Variablen sind immer im Körper der Funktion definiert, die sie deklariert, und die Funktionen, die es nester macht.
Um genau zu sein, gehören die Parameter der Funktion auch zur Kategorie lokaler Variablen. Dieser Satz ist auch sehr wichtig! ! !
Dieser Satz bedeutet grob, dass eine Variable, die in einer Funktion definiert ist, innerhalb der gesamten Funktion gültig ist. Das Ergebnis ist also nicht schwer zu verstehen. Wenn Sie auf unsere Frage zurückblicken, verstehen Sie?
Die Wirkungskette hat auch die folgenden Definitionen:
1. Die Aktionskette besteht aus einem globalen Objekt.
2. In der Funktionskörper, die keine Verschachtung enthält, befinden sich zwei Objekte in der Aktionskette. Das erste Objekt definiert die Funktionsparameter und lokalen Variablen, und das zweite ist das globale Objekt.
3. In einer verschachtelten Funktionskörper gibt es mindestens drei Objekte in der Aktionskette.
Wenn eine Funktion definiert ist, wird eine Bereichskette gespeichert.
Wenn diese Funktion aufgerufen wird, erstellt sie ein neues Objekt, um ihre lokalen Variablen zu speichern, und fügt dieses Objekt der gespeicherten Aktionskette hinzu. Erstellen Sie gleichzeitig eine neue längere Kette von Funktionen, die Funktionsaufrufe darstellen.
Bei verschachtelten Funktionen wird die interne Funktion erneut definiert, wenn die externe Funktion aufgerufen wird. Denn jedes Mal, wenn eine externe Funktion aufgerufen wird, ist die Aktionskette unterschiedlich. Interne Funktionen haben jedes Mal subtile Unterschiede, wenn sie definiert werden. Jedes Mal, wenn die externe Funktion aufgerufen wird, ist der Code der internen Funktion gleich und der Umfang des zugehörigen Codes ist ebenfalls unterschiedlich.
Schließung
Nachdem ich es so lange gemacht hatte, musste ich endlich darüber sprechen, aber lassen Sie uns den Umfang vorher analysieren.
<Script> var namg = "global" var g = function f () {console.log (name); function Demo () {console.log ("Demo =" + name);} var name = ""; namg);} Demo (); Demo (); Demo ();}; g (); </script>Wir analysieren gemäß der Aktionskette:
Rufen Sie Demo0 an, Demo0 () -> Name finden, nicht gefunden -> f (), zurückkehren
Rufen Sie Demo1, Demo1 ()-> NAME FINDEN, FINDEN, RECHTEN
Rufen Sie Demo2 an, Demo2 () -> NAMEG Finden, nicht gefunden -> f (), um ein NAMEG zu finden, nicht gefunden -> Fenster, um NAMEG zu finden, zurückgeben.
Sehen Sie sich dieses Beispiel an:
<Script> Funktion f () {var count =; return {counter: function () {return count ++;}, reset: function () {return count =;}}} var d = f (); var c = f (); console.log ("d erster Anruf:"+ d.counter (); // console.log ("c" c Call: "+ counter (). Rufen Sie: "+ c.Counter ()); // </script>Wie Sie in diesem Beispiel sehen können, habe ich eine Zähl- und Nulloperation durchgeführt.
Es werden zwei Objektinstanzen von F erstellt, die jeweils eine eigene Zielfernrohrkette haben, sodass sich ihre Werte nicht auswirken. Wenn C das zweite Mal bezeichnet wird, wird der Zählwert gespeichert, da das C -Objekt nicht zerstört wird. Erst nach dem Verständnis dieses Beispiels ist das folgende Beispiel leichter zu verstehen.
Jeder sollte sehr klar in diesem Prozess sein. Schauen wir uns nun das Verschlussproblem an. Ich setze vier Schaltflächen ein und klicke auf jede Schaltfläche, um den Namen der Antwort zurückzugeben.
<body> <Script> Funktion btninit () {für (var i =; i <; i ++) {var btn = document.getElementById ("Btn" + i); id = "btn"> btn </button> <button id = "btn"> btn </button> <button id = "btn"> btn </button> <button id = "btn"> btn </button> </div> </body>Klicken Sie zum Ausführen, aber das Ergebnis ist alles BTN5;
Wir haben uns gerade mit der Analyse zusammengesetzt. Zunächst müssen wir die anonyme Funktion aufrufen -> find i, nicht gefunden -> btninit () und fand i in der für Schleife. auftauchen. Wir wissen, dass nur der Funktionsaufruf veröffentlicht wird, und das I -in ist immer sichtbar, sodass der letzte I -Wert beibehalten wird. Also wie man es löst.
Um das Problem zu lösen, dass der I -Wert in der Funktion nicht immer sichtbar ist, müssen wir die Verschachtelung der Funktion verwenden und den I -Wert darin übergeben.
Funktion btninit () {für (var i =; i <; i ++) {(function (data_i) {var btn = document.getElementById ("Btn" + data_i);Führen Sie zuerst den ersten für den geänderten Code aus und erstellen Sie ein Objekt. Wir führen zuerst die anonyme Funktion -> data_i aus, aber nicht gefunden -> Funktion (data_i) und dann erneut für das Erstellen eines Objekts aus. Die Schließungsregeln sagen, dass sie sich nicht gegenseitig beeinflussen. Das richtige Ergebnis kann also erzielt werden.
Das obige ist die JavaScript-Funktion, die Sie Ihnen vorstellen müssen. Wenn ich von den relevanten Kenntnissen über Schließungsfragen spreche, hoffe ich, dass es Ihnen hilfreich sein wird. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Editor wird Ihnen rechtzeitig antworten. Vielen Dank für Ihre Unterstützung auf der Wulin.com -Website!