Grundlagen
Zuerst benötigen wir einen Überblick über das Modulmuster (gebloggt von Eric Miraglia von YUI in 2007 vorgeschlagen), wenn Sie bereits mit dem Modulmodus vertraut sind, können Sie diesen Abschnitt überspringen und direkt „Erweiterter Modus“ lesen.
Verwandte Lernempfehlungen: Javascript-Video-Tutorial
Anonyme Funktionsschließung
Anonyme Funktionsschließungspakete sind die beste Funktion von JavaScript, sie machen alles möglich. Jetzt erstellen wir eine anonyme Funktion und führen sie sofort aus. Der gesamte Code in der Funktion wird in einem Abschluss ausgeführt, und der Abschluss bestimmt den Datenschutz und den Status dieser Codes während des gesamten Ausführungsprozesses.
Der Code lautet wie folgt:
(function () { // ... all vars and functions are in this scope only // still maintains access to all globals }());
Beachten Sie die Klammern außerhalb der anonymen Funktion. Dies liegt daran, dass Anweisungen, die in JavaScript mit „function“ beginnen, im Allgemeinen als Funktionsdeklarationen betrachtet werden. Durch das Hinzufügen äußerer Klammern wird ein Funktionsausdruck erstellt.
Globaler Import
JavaScript verfügt über eine Funktion namens versteckte globale Variablen. Wenn ein Variablenname verwendet wird, sucht der Compiler nach der Anweisung und verwendet var, um die Variable zu deklarieren. Wenn die Variable nicht gefunden wird, gilt sie als global. Bei einer solchen Verwendung während der Zuweisung wird ein globaler Bereich erstellt. Dies bedeutet, dass es sehr einfach ist, eine globale Variable in einem anonymen Abschluss zu erstellen. Leider kann dies zu unüberschaubarem Code führen, da für den Programmierer unklar ist, ob globale Variablen nicht in einer Datei deklariert sind. Glücklicherweise bieten uns anonyme Funktionen eine weitere Möglichkeit. Wir können globale Variablen über die Parameter anonymer Funktionen in unseren Code importieren, was schneller und übersichtlicher ist.
Der Code lautet wie folgt:
(function ($, YAHOO) { // now have access to globals jQuery (as $) and YAHOO in this code }(jQuery, YAHOO));
Modulexport
Manchmal möchten Sie keine globalen Variablen verwenden, aber Sie möchten sie zu erklären. Wir können sie einfach über den Rückgabewert anonymer Funktionen exportieren. Soviel zum Grundinhalt des Modulmusters, hier ist ein komplizierteres Beispiel.
Der Code lautet wie folgt:
var MODULE = (function () { var my = {}, privateVariable = 1; function privateMethod() { // ... } my.moduleProperty = 1; my.moduleMethod = function () { // ... }; return my; }());
Hier deklarieren wir ein globales Modul namens MODULE, das zwei öffentliche Eigenschaften hat: eine Methode namens MODULE.moduleMethod und eine Variable namens MODULE.moduleProperty. Darüber hinaus behält es den privaten internen Status durch das Schließen anonymer Funktionen bei. Natürlich können wir auch den zuvor erwähnten Modus verwenden, um die erforderlichen globalen Variablen einfach zu importieren
Erweiterter Modus
Was ich zuvor erwähnt habe, reicht für viele Bedürfnisse aus, aber wir können tiefer in dieses Muster eintauchen, um einige leistungsstarke skalierbare Strukturen zu erstellen. Lassen Sie uns Schritt für Schritt durch dieses Modul namens MODUL weiterlernen.
Erweiterung
Derzeit besteht eine Einschränkung des Modulmodus darin, dass das gesamte Modul in eine Datei geschrieben werden muss. Jeder, der umfangreiche Codeentwicklung durchgeführt hat, weiß, wie wichtig es ist, eine Datei in mehrere Dateien aufzuteilen. Glücklicherweise haben wir eine großartige Möglichkeit, Module zu erweitern. Zuerst importieren wir ein Modul, fügen dann Attribute hinzu und exportieren es schließlich. Das Beispiel hier ist die Erweiterung von MODULE mit der oben genannten Methode.
Der Code lautet wie folgt:
var MODULE = (function (my) { my.anotherMethod = function () { // added method... }; return my; }(MODULE));
Obwohl unnötig, verwenden wir aus Konsistenzgründen erneut das Schlüsselwort var. Anschließend wird der Code ausgeführt und das Modul fügt eine öffentliche Methode namens MODULE.anotherMethod hinzu. Die Erweiterungsdatei behält auch ihren eigenen privaten internen Status und ihre Importe bei.
Lose Erweiterung
In unserem obigen Beispiel müssen wir zuerst das Modul erstellen und dann das Modul erweitern. Dies ist nicht erforderlich. Das asynchrone Laden von Skripten ist eine der besten Möglichkeiten, die Leistung Ihrer Javascript-Anwendungen zu verbessern. . Durch lose Erweiterung erstellen wir flexible Module, die in beliebiger Reihenfolge geladen und in mehrere Dateien aufgeteilt werden können. Die Struktur jeder Datei ist ungefähr wie folgt
Der Code lautet wie folgt:
var MODULE = (function (my) { // add capabilities... return my; }(MODULE || {}));
In diesem Modus ist die var-Anweisung erforderlich. Wenn das importierte Modul nicht existiert, wird es erstellt. Das bedeutet, dass Sie Tools wie LABjs verwenden können, um diese Moduldateien parallel zu laden.
Enge Erweiterung
Eine lockere Erweiterung ist zwar großartig, bringt aber auch einige Einschränkungen für Ihr Modul mit sich. Der wichtigste Punkt ist, dass Sie keine Möglichkeit haben, Modulattribute sicher zu überschreiben, und dass Sie während der Initialisierung keine Modulattribute in anderen Dateien verwenden können (Sie können sie jedoch während der Laufzeit nach der Initialisierung verwenden). Die kompakte Erweiterung beinhaltet eine bestimmte Ladereihenfolge, unterstützt jedoch das Umschreiben. Hier ist ein Beispiel (Erweitern unseres ursprünglichen MODULS).
Der Code lautet wie folgt:
var MODULE = (function (my) { var old_moduleMethod = my.moduleMethod; my.moduleMethod = function () { // method override, has access to old through old_moduleMethod... }; return my; }(MODULE));
Hier haben wir MODULE.moduleMethod umgeschrieben und den Verweis auf die ursprüngliche Methode nach Bedarf beibehalten.
Kopieren und Vererben
Der Code lautet wie folgt:
var MODULE_TWO = (function (old) { var my = {}, key; for (key in old) { if (old.hasOwnProperty(key)) { my[key] = old[key]; } } var super_moduleMethod = old.moduleMethod; my.moduleMethod = function () { // override method on the clone, access to super through super_moduleMethod }; return my; }(MODULE));
这种模式可能是最不灵活的选择。虽然它支持了一些优雅的合并,但是代价是牺牲了灵巧性。在我们写的代码中,那些类型是对象或者函数的属性不会被复制,只会以一个对象的两份引用的形式存在。一个改变,另外一个也改变。对于对象来说[g5] ,我们可以通过一个递归的克隆操作来解决,但是对于函数是没有办法的,除了eval。然而,为了完整性我还是包含了它。
跨文件的私有状态
把一个module分成多个文件有一很大的局限,就是每一个文件都在维持自身的私有状态,而且没有办法来获得其他文件的私有状态。这个是可以解决的,下面这个松拓展的例子,可以在不同文件中维持私有状态。
代码如下:
var MODULE = (function (my) { var _private = my._private = my._private || {}, _seal = my._seal = my._seal || function () { delete my._private; delete my._seal; delete my._unseal; }, _unseal = my._unseal = my._unseal || function () { my._private = _private; my._seal = _seal; my._unseal = _unseal; }; // permanent access to _private, _seal, and _unseal return my; }(MODULE || {}));
每一个文件可以为它的私有变量_private设置属性,其他文件可以立即调用。当module加载完毕,程序会调用MODULE._seal(),让外部没有办法接触到内部的 _.private。如果之后module要再次拓展,某一个属性要改变。在载入新文件前,每一个文件都可以调用_.unsea(),,在代码执行之后再调用_.seal。
这个模式在我今天的工作中想到的,我从没有在其他地方见到过。但是我认为这是一个很有用的模式,值得单独写出来。
Sub-modules
最后一个高级模式实际上是最简单的,有很多创建子module的例子,就像创建一般的module一样的。
代码如下:
MODULE.sub = (function () { var my = {}; // ... return my;}());
虽然这可能是很简单的,但是我决定这值得被写进来。子module有一般的module所有优质的特性,包括拓展和私有状态。
总结
大多数高级模式都可以互相组合来创建更有用的新模式。如果一定要让我提出一个设计复杂应用的方法的话,我会结合松拓展,私有状态,和子module。
在这里我没有提到性能相关的事情,但是我可以说,module模式对于性能的提升有好处。它可以减少代码量,这就使得代码的载入更迅速。松拓展使得并行加载成为可能,这同样提升的载入速度。初始化的时间可能比其他的方法时间长,但是这多花的时间是值得的。只要全局变量被正确导入了运行的时候就不会出问题,在子module中由于对变量的引用链变短了可能也会提升速度。
最后,这是一个子module自身动态加载的例子(如果不存在就创建),为了简介我没有考虑内部状态,但是即便考虑它也很简单。这个模式可以让复杂,多层次的代码并行的加载,包括子module和其他所有的东西。
代码如下:
var UTIL = (function (parent, $) { var my = parent.ajax = parent.ajax || {}; my.get = function (url, params, callback) { // ok, so I'm cheating a bit return $.getJSON(url, params, callback); }; // etc... return parent; }(UTIL || {}, jQuery));
我希望这些内容是有用的,请在下面留言来分享你的想法。少年们,努力吧,写出更好的,更模块化的JavaScript。
Das obige ist der detaillierte Inhalt vonEingehende Analyse der Modulmusterprogrammierung von JavaScript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!