2 Stimmen

Wie kann ich den Überblick über mehrere Durchläufe derselben Funktion behalten?

Ich habe eine Funktion wie diese:

function run(arg) {
    if (!window.alreadyRun) init();
    window.alreadyRun = true;
    /* more code */
}

Sie verstehen schon, ich versuche herauszufinden, ob es das erste Mal ist, dass eine Funktion aufgerufen wird.

Gibt es eine bessere Möglichkeit, dies zu tun? Ohne Verwendung von Globals? Etwas wie dies:

function run(arg) {
    var ranAlready;
    if (!ranAlready) init();
    ranAlready = true;
    /* more code */
}

5voto

alex Punkte 457905

Dies gibt eine Funktion zurück, mit einer Variablen namens runCount in dem die Anzahl der Aufrufe gespeichert wird.

var yourFunction = function() {
    var runCount = 0;

    return function() {
        console.log(runCount);
        runCount++;
    }  

}

var a = yourFunction();

a(); // runCount: 0
a(); // runCount: 1
a(); // runCount: 2
a(); // runCount: 3

Siehe auf jsFiddle .

Wenn Sie nur eine Funktion vom Typ init ausführen möchten, können Sie den obigen Code so platzieren, dass die innere Funktion zurückgegeben wird. Er wird einmal aufgerufen, bevor die innere Funktion zurückgegeben wird, und sein Geltungsbereich bleibt auf die äußere Funktion beschränkt.

2voto

Raynos Punkte 162170

Die Macht der Verschlüsse.

var f = (function(run) {
    return function() {
        if (!run) init(),run=true;
        // do code
    };
}(false));

Sie können sogar if (!run) init() && run = true und erhalten init zur Rückkehr false wenn Sie möchten, dass sie beim nächsten Funktionsaufruf erneut aufgerufen wird.

Wir haben eine selbstausführende Funktion, die eine lokale run Variable und setzt sie auf false indem Sie es als Argument übergeben. Wir haben dann eine einzige Zeile, die prüft, ob es sich um false wenn ja, dann init(), run=true die die init Funktion und deren Zuweisung an true in einem einzigen Ausdruck.

Grundsätzlich überall, wo Ihr mit globalen Bereich, um die Variable statisch auf die Funktion können Sie stattdessen eine Schließung als Bereichsebene zwischen lokalen Funktionsbereich & globalen Bereich verwenden.

Wenn Sie eine Variable benötigen, die für eine Funktion statisch und nur lesbar ist, können Sie die wenig bekannte const Stichwort.

1voto

David Tang Punkte 89390

Ich denke, Schließungen sind völlig überflüssig für diese, und verkompliziert nur den Code.

Was Sie beschreiben, ist als statische Variable in objektorientierten Sprachen bekannt, und es kann ganz einfach in JS nachgeahmt werden, indem Eigenschaften direkt an die Funktion angehängt werden. Dies ist möglich, weil Funktionen in JS Objekte erster Klasse sind:

function run(arg) {
    if (!run.ranAlready) { // run.ranAlready is undefined at first, so falsy
       run.ranAlready = true;
       init();
    }

    /* more code */
}

Dies ist viel einfacher als verschachtelte Funktionen, und Sie können weiterhin die run() auf genau die gleiche Weise.

Ein weiterer Vorteil ist, dass Sie für Unit-Tests weiterhin auf die ranAlready Eigenschaft von außerhalb der Funktion, um zu prüfen, ob Ihr Code korrekt funktioniert:

assert(run.runAlready == false);
run();
assert(run.runAlready === true);

Zugegeben, dies kann nicht für anonyme Funktionen verwendet werden, wie z.B. in Event-Handlern, aber ist es nicht viel sauberer, wenn man dieser anonymen Funktion einen Namen geben anstatt verschachtelte Funktionen und einen zusätzlichen Funktionsaufruf zu verwenden?

0voto

Jonathon Bolster Punkte 15681

Hier ist eine weitere Möglichkeit, dies zu tun. Sie können die Funktion selbst ändern lassen. In dem Fall unten, myfunction wird durch eine neue ersetzt. Diese Mai nicht genau das sein, wonach Sie suchen, aber ich denke, es ist nützlich, dies zumindest zu posten, damit Sie alternative Wege sehen können, um Dinge zu tun (und auch: selbst modifizierende Code kann einfach cool manchmal sein).

var myfunction = function() {
    alert("This is the first time I'm executed");

    myfunction = function() {
        alert('Subsequent times');
    }
}

myfunction();  // displays the alert 'This is the first time...'
myfunction();  // displays the alert 'Subsequent times'
myfunction();

http://jsfiddle.net/jonathon/wntmB/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X