17 Stimmen

Warum das JavaScript-Klasse in einem anonymen function() Aufruf einbinden?

Ich habe über die neue von Microsoft namens TypeScript gelesen. Im Spielplatz (Beispielbereich) gibt es eine einfache Klasse in TypeScript-Syntax, die in JavaScript-Code umgewandelt wurde. Da ich aus einem Java-Programmierhintergrund komme, fand ich es interessant zu lernen, wie OOP in JavaScript als von TypeScript übersetzt ausgeführt wird.

Der TypeScript-Code:

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}   

var greeter = new Greeter("Welt");

var button = document.createElement('button')
button.innerText = "Sag Hallo"
button.onclick = function() {
    alert(greeter.greet())
}

document.body.appendChild(button)

Und der entsprechende JavaScript-Code:

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
var greeter = new Greeter("Welt");
var button = document.createElement('button');
button.innerText = "Sag Hallo";
button.onclick = function () {
    alert(greeter.greet());
};
document.body.appendChild(button);

Der TypeScript-Teil ähnelt sehr Java, also verstehe ich das. Jetzt ist meine Frage, warum in JavaScript der Körper der Greeter-Klasse in einem anonymen function()-Aufruf eingebettet ist?

Warum nicht so schreiben?

function Greeter(message) {
    this.greeting = message;
}
Greeter.prototype.greet = function () {
    return "Hello, " + this.greeting;
};

Was sind die Vor- und Nachteile der beiden Methoden?

15voto

Alex Punkte 34091

Das folgende wird als Immediately Invoked Function Expression bezeichnet:

(function(){ ... })();

Es wird verwendet, um den globalen Bereich sauber zu halten. Obwohl es in diesem Fall nicht notwendig ist, da der Rückgabewert einer Variable Greeter zugewiesen wird. Das einzige Mal, dass dieses Muster nützlich ist, ist, wenn Sie "private" static Elemente möchten.

Zum Beispiel:

var Greeter = (function () {
    var foo = 'foo', bar = 'bar'; /* nur von Funktionen im lokalen Bereich zugänglich ... */

    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hallo, " + this.greeting;
    };
    return Greeter;
})();

3voto

Mark Porter Punkte 1630

Dies dient dazu, private Elemente zu ermöglichen. In diesem Beispiel sind alle Elemente öffentlich, sodass Ihre beiden Konstruktionen äquivalent sind. Wenn Sie jedoch private Elemente bereitstellen möchten, müssen Sie sie über einen Closure aus dem Aufrufbereich ausblenden. Wenn Sie also ein privates Element haben wie hier:

class Greeter {
    private greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hallo, " + this.greeting;
    }
} 

Erhalten Sie wahrscheinlich etwas Ähnliches wie dies:

var Greeter = (function () {
    var greeting="";
    function Greeter(message) {
        greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hallo, " + greeting;
    };
    return Greeter;
})();

Die Variable greeting ist für alle Funktionen innerhalb der anonymen Funktion sichtbar, aber nirgendwo sonst.

3voto

Louis Ricci Punkte 20310

Außer den offensichtlichen Gründen für den Geltungsbereich/Abfälligkeitsgründe. Die Verwendung einer anonymen Funktion, die sich sofort selbst aufruft, lädt die Klassendefinition vor (interpretiert). Dies ermöglicht es, dass alle JIT-Optimierungen direkt am Anfang der Ausführung geladen werden. Kurz gesagt, für größere, komplexere Anwendungen wird dies die Leistung verbessern.

2voto

Jordan Denison Punkte 2569

Die anonyme Funktion / selbstausführende Closure wird in der Regel verwendet, um den Gültigkeitsbereich zu kapseln, so dass nur der zurückgegebene Wert außerhalb davon zugänglich ist. (oder irgendetwas, das Sie an andere Objekte anhängen, wie z.B. window)

1voto

Deleteman Punkte 8210

Die anonyme Funktion ist wahrscheinlich vorhanden, um Namenskonflikte mit anderen Teilen des Codes zu verhindern. Stellen Sie es sich so vor, innerhalb Ihrer anonymen Funktion könnten Sie sogar eine Variable namens "$" deklarieren, die sein kann, was immer Sie wollen, und gleichzeitig jQuery in anderen Teilen Ihres Codes ohne Konflikt verwenden.

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