Die modulare Programmierung ist ein sehr häufiges JavaScript -Programmiermuster. Es kann im Allgemeinen den Code erleichtern, das Verständnis zu verstehen, aber es gibt viele hervorragende Praktiken, die nicht bekannt sind.
Base
Lassen Sie uns zunächst kurz einige modulare Muster skizzieren, da Eric Miraglia (der Entwickler von Yui) vor drei Jahren zum ersten Mal einen Blog veröffentlicht hat, in dem modulare Muster beschrieben wurden. Wenn Sie mit diesen modularen Modi bereits sehr vertraut sind, können Sie diesen Abschnitt direkt überspringen und mit dem "Erweiterten Modus" lesen.
Anonyme Schließung
Dies ist eine Grundstruktur, die alles möglich macht, und es ist auch das beste Merkmal von JavaScript. Wir werden einfach eine anonyme Funktion erstellen und sie sofort ausführen. Der gesamte Code wird in dieser Funktion ausgeführt und lebt in einer Schließung, die die Privatisierung bietet. Dies reicht aus, um die Variablen in diesen Schließungen zu ermöglichen, das gesamte Leben unserer Anwendung zu durchlaufen.
Die Codekopie lautet wie folgt:
(function () {
// ... alle Vars und Funktionen sind nur in diesem Bereich enthalten
// behält immer noch den Zugriff auf alle Globalen bei
} ());
Beachten Sie die äußersten Klammern dieses Paares, das anonyme Funktionen einpackt. Aufgrund der Sprachmerkmale von JavaScript ist dies für Klammern erforderlich. Aussagen beginnen mit der Schlüsselwortfunktion in JS immer als Funktion als deklarativ angesehen. Wickeln Sie diesen Code in Klammern ein, um den Interpreter wissen zu lassen, dass dies ein Funktionsausdruck ist.
Globaler variabler Import
JavaScript verfügt über eine Funktion namens Implicit Global Variablen. Unabhängig davon, wo ein Variablenname verwendet wird, wird der Interpreter die VAR -Deklarationsanweisung der Variablen entsprechend der Bereichskette umgekehrt ermittelt. Wenn die VaR -Deklarations -Anweisung nicht gefunden wird, wird diese Variable als globale Variable angesehen. Wenn diese Variable in einer Zuordnungsanweisung verwendet wird und die Variable nicht vorhanden ist, wird eine globale Variable erstellt. Dies bedeutet, dass es einfach ist, globale Variablen in anonymen Schließungen zu verwenden oder zu erstellen. Leider macht es den Code, den geschriebenen Code geschrieben hat, äußerst schwierig, da es für intuitive Gefühle der Menschen auf einen Blick unmöglich zu sagen ist, dass diese Variablen global sind.
Glücklicherweise bieten unsere anonymen Funktionen einfache Problemumgehungen. Geben Sie einfach die globale Variable als Parameter in unsere anonyme Funktion über, Sie können klarer und schnellerer Code als die implizite globale Variable erhalten. Hier ist ein Beispiel:
Die Codekopie lautet wie folgt:
(Funktion ($, yahoo) {
// haben nun Zugriff auf Globals JQuery (als $) und Yahoo in diesem Code
} (jQuery, yahoo));
Modulexport
Manchmal möchten Sie nicht nur globale Variablen verwenden, Sie möchten sie auch für den wiederholten Gebrauch deklarieren. Wir können dies leicht tun, indem wir sie durch den Rückgabewert der anonymen Funktionen abgeben. Dies wird ein grundlegendes modulares Modell abschließen, und das folgende wird ein vollständiges Beispiel sein:
Die Codekopie lautet wie folgt:
var module = (function () {
var my = {},
privateVariable = 1;
Funktion privatemethod () {
// ...
}
my.moduleProperty = 1;
my.modulemethod = function () {
// ...
};
kehre meine zurück;
} ());
Beachten Sie, dass wir ein globales Modul namens Modul mit zwei öffentlichen Eigenschaften deklariert haben: eine Methode namens modul.modulemethod und eine Variable namens Modul.ModuleProperty. Darüber hinaus unterhält es einen privaten integrierten Zustand, der anonyme Funktionsverschlüsse verwendet. Gleichzeitig können wir die erforderlichen globalen Variablen problemlos importieren und dieses modulare Muster verwenden, wie wir zuvor gelernt haben.
Erweiterter Modus
Die im obigen Abschnitt beschriebene Grundlage reicht aus, um mit vielen Situationen umzugehen, und jetzt können wir dieses modulare Modell weiterentwickeln, um leistungsstärkere und skalierbare Strukturen zu erstellen. Beginnen wir mit dem Modulmodul und stellen diese erweiterten Modi einzeln ein.
Zoommodus
Das gesamte Modul muss eine Einschränkung des modularen Modus in einer Datei sein. Jeder, der an einem großen Projekt beteiligt ist, wird den Wert der Aufteilung mehrerer Dateien mit JS verstehen. Glücklicherweise haben wir eine großartige Implementierung, um die Module zu verstärken. Zunächst importieren wir ein Modul, fügen ihm Eigenschaften hinzu und exportieren es schließlich. Hier ist ein Beispiel: Zoom aus dem ursprünglichen Modul:
Die Codekopie lautet wie folgt:
var module = (function (my) {
my.anothermethod = function () {
// Methode hinzugefügt ...
};
kehre meine zurück;
}(MODUL));
Wir verwenden das VAR -Schlüsselwort, um Konsistenz zu gewährleisten, obwohl es hier nicht erforderlich ist. Nachdem dieser Code ausgeführt wurde, verfügt unser Modul bereits über eine neue öffentliche Methode namens Modul.anothermethod. Diese vergrößerte Datei führt auch einen eigenen privaten integrierten Zustand und importierten Objekte.
Breiter Zoommodus
In unserem obigen Beispiel muss unser Initialisierungsmodul zuerst ausgeführt und dann ein Verstärkungsmodul ausgeführt werden, und natürlich ist dies natürlich möglicherweise nicht unbedingt erforderlich. Eines der besten Dinge, die JavaScript -Anwendungen zur Verbesserung der Leistung tun können, besteht darin, Skripte asynchron auszuführen. Wir können flexible Mehrfachmodule erstellen und ermöglichen, dass sie in beliebiger Reihenfolge über einen breiten Zoommodus geladen werden. Jede Datei muss in der folgenden Struktur organisiert werden:
Die Codekopie lautet wie folgt:
var module = (function (my) {
// Funktionen hinzufügen ...
kehre meine zurück;
} (Modul || {}));
In diesem Muster macht es der VAR -Ausdruck notwendig. Beachten Sie, dass diese Importanweisung, wenn das Modul nicht initialisiert wurde, ein Modul erstellt. Dies bedeutet, dass Sie ein Tool wie LabJs verwenden können, um alle Ihre Moduldateien parallel zu laden, ohne blockiert zu werden.
Enger Vergrößerungsmodus
Der Wide-Enlarge-Modus ist sehr gut, aber auch einige Einschränkungen für Ihr Modul. Am wichtigsten ist, dass Sie die Eigenschaften eines Moduls nicht sicher überschreiben können. Sie können bei der Initialisierung keine Eigenschaften aus anderen Dateien verwenden (aber Sie können sie beim Ausführen verwenden). Der enge Vergrößerungsmodus enthält eine geladene Sequenz und ermöglicht überschreibende Eigenschaften. Hier ist ein einfaches Beispiel (Zoom in unserem ursprünglichen Modul):
Die Codekopie lautet wie folgt:
var module = (function (my) {
var old_modulemethod = my.modulemethod;
my.modulemethod = function () {
// Methode Override hat Zugriff auf Old über old_modulemethod ...
};
kehre meine zurück;
}(MODUL));
Wir überschreiben die Implementierung von Modul.Modulemethod im obigen Beispiel, aber bei Bedarf können wir einen Verweis auf die ursprüngliche Methode beibehalten.
Klon und Erbschaft
Die Codekopie lautet wie folgt:
var module_two = (function (alt) {
var my = {},
Schlüssel;
für (Schlüssel in alt) {
if (old.hasownProperty (Schlüssel)) {
mein [Schlüssel] = alt [Schlüssel];
}
}
var super_modulemethod = old.modulemethod;
my.modulemethod = function () {
// Überschreiben Sie die Methode im Klon, Zugriff auf Super über Super_Modulemethod
};
kehre meine zurück;
}(MODUL));
Dieses Modell ist wahrscheinlich die unflexibelste Option. Es lässt den Code ordentlich aussehen, aber das kommt auf Kosten der Flexibilität. Wie ich oben geschrieben habe, wird sie nicht kopiert, wenn eine Eigenschaft ein Objekt oder eine Funktion ist, sondern wird der zweite Verweis auf das Objekt oder die Funktion. Wenn Sie einen von ihnen ändern, ändern Sie den anderen gleichzeitig (Anmerkung des Übersetzers: weil sie einfach eins sind!). Dies kann durch rekursives Klonierungsprozess gelöst werden, aber das Funktionskloning kann nicht gelöst werden, vielleicht kann es mit Eval gelöst werden. Daher erzähle ich diese Methode in diesem Artikel nur die Integrität des Artikels.
Cross-file private Variablen
Die Aufteilung eines Moduls in mehrere Dateien ist eine erhebliche Einschränkung: Jede Datei verwaltet ihre eigenen privaten Variablen und kann für andere Dateien nicht auf private Variablen zugreifen. Aber dieses Problem kann gelöst werden. Hier ist ein Beispiel für ein weitgehendes Modul, das private Variablen über Dateien hinweg verwaltet:
Die Codekopie lautet wie folgt:
var module = (function (my) {
var _private = my._private = my._private || {},
_Seal = my._seal = my._seal || function () {
löschen my._private;
my._seal löschen;
my._unseal löschen;
},
_unseal = my._unseal = my._unseal || function () {
my._private = _private;
my._seal = _Seal;
my._unseal = _unseal;
};
// ständiger Zugriff auf _private, _Seal und _unseal
kehre meine zurück;
} (Modul || {}));
Alle Dateien können Eigenschaften auf ihren jeweiligen Variablen festlegen, und es versteht, dass sie von anderen Dateien zugegriffen werden können. Sobald dieses Modul geladen ist, kann die Anwendung Modul._Seal () aufrufen, um externe Aufrufe auf interne _private zu verhindern. Wenn dieses Modul neu gestaltet werden muss, kann die interne Methode in einer beliebigen Datei vor dem Laden der neuen Datei _unSeal () aufrufen und _seal () erneut aufrufen, nachdem die neue Datei ausgeführt wurde. Ich benutze dieses Muster jetzt bei der Arbeit und ich habe es nirgendwo anders gesehen. Ich denke, dies ist ein sehr nützliches Modell und es lohnt sich, einen Artikel über dieses Modell selbst zu schreiben.
Submodules
Unser letzter fortgeschrittener Modus ist offensichtlich der einfachste. Es gibt viele hervorragende Beispiele für die Erstellung von Submodulen. Es ist wie ein normales Modul zu erstellen:
Die Codekopie lautet wie folgt:
Module.sub = (function () {
var my = {};
// ...
kehre meine zurück;
} ());
Obwohl dies einfach erscheint, denke ich, dass es hier erwähnenswert ist. Submodule haben alle fortgeschrittenen Vorteile von allgemeinen Modulen, einschließlich des Verstärkungsmodus und des Privatisierungszustands.
abschließend
Die meisten erweiterten Modi können kombiniert werden, um einen nützlicheren Modus zu erstellen. Wenn ich wirklich ein modulares Muster für das Entwerfen komplexer Anwendungen empfehlen möchte, würde ich mich für den breiten Verstärkungsmodus, private Variablen und Submodule kombinieren.
Ich habe die Leistung dieser Modi nicht in Betracht gezogen, aber ich würde dies lieber in eine einfachere Denkweise verwandeln: Wenn ein modularer Modus eine gute Leistung hat, kann er eine hervorragende Arbeit leisten, um sie zu minimieren und diese Skriptdatei schneller herunterzuladen. Die Verwendung des breiten Vergrößerungsmodus ermöglicht einfache, nicht blockierende parallele Downloads, die Downloads beschleunigt. Die Initialisierungszeit kann etwas langsamer sein als andere Methoden, aber es lohnt sich, die Vor- und Nachteile abzuwägen. Solange der globale variable Import korrekt ist, sollte die Laufzeitleistung beeinträchtigt werden, und es ist auch möglich, schnellere Laufgeschwindigkeiten in Submodule durch Verkürzung der Referenzkette mit privaten Variablen zu erreichen.
Als Schlussfolgerung ist hier ein Beispiel für ein untergeordnetes Modul, das sich dynamisch in sein übergeordnetes Modul lädt (erstellen, wenn das übergeordnete Modul nicht existiert). Der Einfachheit halber habe ich die privaten Variablen entfernt und es ist natürlich sehr einfach, private Variablen hinzuzufügen. Dieses Programmiermuster ermöglicht es, eine gesamte komplexe hierarchische Struktur -Code -Basis parallel durch Submodule zu laden.
Die Codekopie lautet wie folgt:
var util = (Funktion (übergeordnet, $) {
var my = parent.ajax = parent.ajax || {};
My.get = Funktion (URL, Params, Rückruf) {
// ok, also betrüge ich ein bisschen :)
$ .getJson zurückgeben (URL, Params, Rückruf);
};
// usw...
Eltern zurückgeben;
} (Util || {}, jQuery));
Dieser Artikel fasst die aktuellen Best Practices von "JavaScript Modular Programing" zusammen und erklärt, wie sie in die Praxis umsetzen können. Obwohl dies kein primäres Tutorial ist, können Sie es durch ein wenig Verständnis der grundlegenden Syntax von JavaScript verstehen.