Verwendung des Revealing-Modulmusters in JavaScript

78

Ich bin über diesen Beitrag gestolpert: JavaScript's Revealing Module Pattern . Ich möchte dies in meinem Projekt verwenden.

Stellen wir uns vor, ich habe eine Funktion abcund rufe diese Funktion in meiner Haupt-JavaScript-Datei auf.

Macht dieses Muster die Dinge anders? Kann mir jemand ein grundlegendes Beispiel für dieses Muster zeigen?

theJava
quelle
3
Für mich ist dieser Artikel die beste Erklärung, die ich bisher gesehen habe.
Mohammad Sepahvand
2
Warum das Revealing Module Pattern verwenden, wenn Sie das Definitive Module Pattern verwenden können? github.com/tfmontague/definitive-module-pattern
tfmontague

Antworten:

98

Ein kleines Beispiel:

var revealed = function(){
   var a = [1,2,3];
   function abc(){
     return (a[0]*a[1])+a[2];
   }

   return {
      name: 'revealed',
      abcfn: abc
   }
}();

in der anonymen Funktion, die initiiert wird, um revealedeinen Wert anzugeben, aund abcfür diese Funktion privat sind. Was die Funktion zurückgibt, ist ein Objektliteral mit einer nameEigenschaft und einer abcfnEigenschaft, die auf die verweist abc function. Der abc functionverwendet die private Variable a. Dies kann alles dank der Verwendung von Verschlüssen geschehen (alles im Bereich einer Funktion kann von allem anderen in derselben Funktion referenziert werden).

Offenbarte Verwendung:

alert(revealed.name);    //=> 'revealed'
alert(revealed.abcfn()); //=> 5 (1*2+3)
KooiInc
quelle
8
Dieses Muster hat mein Leben verändert!
Klewis
6
Ich weiß, dass dies alt ist, aber der Rückgabewert von abc () fehlt eine Klammer =]
Fillip Peyton
Warum das Revealing Module Pattern verwenden, wenn Sie das Definitive Module Pattern verwenden können? github.com/tfmontague/definitive-module-pattern
tfmontague
Wie erstelle ich eine neue Instanz von enthüllt?
Neon Warge
@ NeonWarge: das tust du nicht. Die Funktion ist kein Konstruktor. Es gibt ein Objektliteral zurück, in dem aund abcgeschlossen sind.
KooiInc
23

DC = Douglas Crockford
RMP = Aufdeckendes Modulmuster

Der Unterschied zwischen DC und RMP ist hauptsächlich organisatorisch / lesbar

Beispiel wird im Artikel selbst vorgestellt? Und was genau fragst du, weil diese Dinge nichts mit Dateien zu tun haben, sondern mit Schließungen.

Sie setzen alles in einen Verschluss (Funktion) und legen nur den Teil frei, auf den Sie zugreifen möchten. Der Unterschied zwischen DC Stil und RMP ist , dass in den ersten Funktionen an verschiedenen Orten definiert werden , während in dem RMP sie immer an der gleichen Stelle definiert und dann später offenbarte in der Öffentlichkeit Objektliteral.

In DC und RMP haben Sie also:

  • Schließung, die es ermöglicht, private Teile (Variablen und Funktionen) zu definieren
  • privater Teil
  • öffentliches Ergebnis, das öffentlich sichtbare Funktionen und Variablen definiert (Status)

Diese beiden Muster unterscheiden sich nur in der Lesbarkeit. Im DC-Fall können Sie nicht immer wissen, wo bestimmte Funktionen definiert werden, aber im RMP wissen Sie immer, dass sich alles im privaten Teil befindet.

Robert Koritnik
quelle
1
Es ist nicht wahr, dass DC und RMP gleich sind - die beiden sind sehr unterschiedlich, wenn es um Vererbung geht. Siehe stackoverflow.com/questions/21925720/… zum Beispiel
I-Lin Kuo
6

Die vom Autor als "Douglas Crockfords Muster zum Erstellen von Objekten" bezeichnete Methode ist eigentlich das Modulmuster, das hauptsächlich von Richard Cornford et al . Siehe http://groups.google.com/group/comp.lang.javascript/msg/9f58bd11bd67d937

Zum Beispiel gibt es viele. Lesen Sie den folgenden Artikel und folgen Sie einigen der Links: http://peter.michaux.ca/articles/module-pattern-provides-no-privacy-at-least-not-in-javascript-tm

RobG
quelle
Ich habe meinen Beitrag überarbeitet, bitte lassen Sie mich wissen, wenn es noch Probleme gibt :)
Alex
Interessant, wie sich diese Dinge im Laufe der Zeit verändern. Die "aufschlussreiche" Version wird seit einiger Zeit von David Mark (von MyLibrary ) verwendet. Ich habe keine Probleme mit der "nicht aufschlussreichen" Version, daher verwende ich diese. :-)
RobG
1

Ich verwende gerne eine Mischung aus dem aufschlussreichen Modulmuster und dem Singleton-Muster, damit ich strukturierten Code mit den Vorteilen des Modulmusters beibehalten kann:

var MyFunction = function(){

    var _ = {
       Init: function(){
          _.Config.foo = "hello world";
       },
       Config:{
          foo:null
       },
       ShowAlert:function(){
          alert(_.Config.foo);
       }
    }

    return {
        Init: _.Init,
        ShowAlert: _.ShowAlert
    };
}();

MyFunction.Init();
MyFunction.ShowAlert();

Ich habe weitere Informationen dazu in meinem Blog geschrieben:

http://curtistimson.co.uk/js/mixing-revealing-module-and-singleton-javascript-patterns/

Curt
quelle
1

Ich möchte nur hinzufügen: Mit diesem Muster ist es gut, globale Abhängigkeiten als Argumente / Parameter zu übergeben, damit sie explizit sind. Sie müssen es nicht tun, aber dies macht auf den ersten Blick deutlich, was Ihr Modul benötigt. Z.B:

var myModule = (function ($, loadModule) {
  "use strict";
})(jQuery, load);

In diesem Beispiel sehen Sie sofort in der ersten Zeile, dass Ihr Modul jQuery und ein anderes Modul verwendet, das für das Laden der Funktionalität verantwortlich ist.

Maria Blair
quelle
0

Für den Code außerhalb des Moduls macht es wenig Unterschied. In allen drei Fällen in diesem Artikel werden die Methoden auf dieselbe Weise aufgerufen. Die Struktur des Moduls selbst ist jedoch intern unterschiedlich.

Crockfords Modulmuster und das, was sie als "aufschlussreiches Modulmuster" bezeichnen, sind strukturell ziemlich dasselbe. Der einzige Unterschied besteht darin, dass sie die Methode zuerst einer lokalen Variablen zuweisen, um besser lesbar zu sein. Aber es gibt wirklich nichts Besonderes, und Sie haben einige Beispiele genau dort in Ihrem Link.

Alex Wayne
quelle
Das vom aufschlussreichen Modulmuster zurückgegebene Objekt verhält sich in Bezug auf das Überschreiben nicht wie das Modulmuster von Douglas Crockford (siehe Warnung von Addy Osmani unter addyosmani.com/resources/essentialjsdesignpatterns/book/… ).
I-Lin Kuo
0

Das Grundkonzept eines Revealing Modul ist , dass Sie eine haben , Objectdie kapselt seine Daten und Verhalten:

var Module = (function(){
    var privateStuff = {};
    var publicStuff = {};

    return publicStuff;
})();

Es gibt jedoch einige bewährte Methoden, die Sie bei der Verwendung dieses Musters anwenden sollten. Hier ist ein Modul (" Modulus") mit einigen Eigenschaften zur Demonstration, das einige dieser Praktiken verwendet:

function AbstractSomeClass(id) {
    this.id = id;
    return this;
}

var Modulus = (new (function SomeClass() {
    var thus = this;

    function NameClass(name){
        this.value = thus.name || name;
    }

    AbstractSomeClass.call(this, 998);

    this.name = 'Touring';
    this.name = ( new NameClass('Hofstadter') ).value;

    return {
        id: this.id,
        name: this.name
    };
})());

Beachten Sie die (new (function SomeClass(){ ... })());Syntax. Wenn newSie so verwenden, können Sie das thisSchlüsselwort innerhalb des Abschlusses verwenden. Dies ist praktisch , wenn Sie zu vererben Eigenschaften von einer anderen Klasse benötigen ( AbstractSomeClass.call(this, 998);) - Allerdings werden Sie noch brauchen , zeigen die Eigenschaften, die Öffentlichkeit haben möchten, zum Beispiel:

return {
    id: this.id,
    name: this.name
};

Beachten Sie auch , dass wir zuweisen thiszu thus- was erlaubt uns , die Parent- zu verwenden thisinnerhalb einer Unterklasse, die ihren eigenen hat thisUmfang ( this.value = thus.name || name;)

Dies sind wiederum nur einige der vorgeschlagenen Konventionen und Best Practices.

Cody
quelle
0

Hier ist das kleine Beispiel für das Aufdecken des Modulmusters.

Es bietet die Möglichkeit, private und öffentliche Funktionen wie eine Klasse zu deklarieren. Dies ist der Hauptvorteil dieses Musters. Wenn wir einige der Funktionen, auf die global zugegriffen werden soll, nicht verfügbar machen möchten, werden sie privat und der Rest öffentlich gemacht ist das Beispiel, wie private und öffentliche Funktionen erstellt werden. Und noch etwas: Es ist ein selbst ausführbarer Codeblock.

  var Calculator = (function () {

        var num1 = 10;
        var num2=5
        var _abc = function () {
            return num1 - num2;
        };

        var _mulFunc = function () {
            return num1 * num2;
        };

        var _divFunc = function () {
            return num1/num2;
        };

        return {
           //public scope
            abc: _abc,
            mulFunc:_mulFunc
         };

    })();

alert (Calculator.abc ()); es gibt 5 zurück

alert (Calculator.mulFunc ()); es gibt 50 zurück

Auf __divFunc () kann nicht zugegriffen werden, da es sich um einen privaten Bereich handelt. Wir können nur auf die Funktionen zugreifen, die im Rückgabeobjekt deklariert sind , da es sich um eine öffentliche Funktionsdarstellung handelt

Sheo Dayal Singh
quelle