2012-04-12 4 views
5

Ich organisiere meinen Code in 20-60 Linienmodule, normalerweise im Modulmuster. Ich möchte eine wohlgeformte objektorientierte JavaScript-Bibliothek.JavaScript-Organisation | Modulmuster w/Module

Ist dies der beste Weg, dies zu tun? Der Code wurde getestet und funktioniert.

Ich mag es, weil ein Programmierer Module aus der Bibliothek ziehen und sie bei Bedarf verwenden kann, sie sind eigenständig.

Hier ist Tool, Nachricht, Effekt und Text, alle in NS enthalten.

Frage?

Ist dies ein guter Weg (Best Practice), um meine Bibliothek zu organisieren?

Hinweis

Bisher gibt es 0 Konsens in den Kommentaren und Antworten ... sehr frustrierend.

Außenmodul Muster

var NS = (function (window, undefined) 
{ 
/* All Modules below here */ 
})(window); 

Werkzeuge

/** 
*Tools 
* getTimeLapse - benchmark for adding 
*/ 

var Tool = (function() 
{ 
    var Tool = function () 
    { 
    }; 
    Tool.prototype.getTimeLapse = function(numberOfAdds) 
    { 
     var end_time; 
     var start_time = new Date().getTime(); 
     var index = 0;   
     while (index <= numberOfAdds) 
     { 
      index++; 
     } 
     end_time = new Date().getTime(); 
     return (end_time - start_time); 
    }; 
    return Tool; 
}()); 

Nachricht

/** 
*Message 
* element - holds the element to send the message to via .innerHTML 
* type - determines the message to send 
*/ 

var Message = (function() 
{ 
    var messages = 
    { 
     name:   'Please enter a valid name', 
     email:  'Please enter a valid email', 
     email_s:  'Please enter a valid email.', 
     pass:   'Please enter passoword, 6-40 characters', 
     url:   'Please enter a valid url', 
     title:  'Please enter a valid title', 
     tweet:  'Please enter a valid tweet', 
     empty:  'Please complete all fields', 
     same:   'Please make emails equal', 
     taken:  'Sorry, that email is taken', 
     validate:  'Please contact <a class="d" href="mailto:[email protected]">support</a> to reset your password', 
    }; 
    var Message = function (element) 
    { 
     this.element = element; 
    }; 
    Message.prototype.display = function(type) 
    { 
     this.element.innerHTML = messages[ type ]; 
    }; 
    return Message; 
}()); 

Effekte

/** 
*Effects 
* element - holds the element to fade 
* direction - determines which way to fade the element 
* max_time - length of the fade 
*/ 

var Effects = (function() 
{ 
    var Effects = function (element) 
    { 
     this.element = element; 
    }; 
    Effects.prototype.fade = function(direction, max_time) 
    { 
     var element = this.element; 
     element.elapsed = 0; 
     clearTimeout(element.timeout_id); 
     function next() 
     { 
      element.elapsed += 10; 
      if (direction === 'up') 
      { 
       element.style.opacity = element.elapsed/max_time; 
      } 
      else if (direction === 'down') 
      { 
       element.style.opacity = (max_time - element.elapsed)/max_time; 
      } 
      if (element.elapsed <= max_time) 
      { 
       element.timeout_id = setTimeout(next, 10); 
      } 
     } 
     next(); 
    }; 
    return Effects; 
}()); 

Text

/** 
*Text 
* form_elment - holds text to check 
*/ 

var Text = (function() 
{ 
    var Text = function (form_element) 
    { 
     this.text_array = form_element.elements; 
    }; 
    Text.prototype.patterns = 
    { 
     prefix_url:  /^(http:)|(https:)\/\//, 
     aml:   /<(.+)_([a-z]){1}>$/, 
     url:   /^.{1,2048}$/, 
     tweet:   /^.{1,40}$/, 
     title:   /^.{1,32}$/, 
     name:   /^.{1,64}$/, 
     email:   /^.{1,64}@.{1,255}$/, 
     pass:   /^.{6,20}$/ 
    }; 
    Text.prototype.checkPattern = function(type) 
    { 
     return this.patterns[ type ].exec(this.text_array[type].value); 
    }; 
    Text.prototype.checkUrl = function(type) 
    { 
     return this.patterns[ type ].exec(this.text_array.url.value); 
    }; 
    Text.prototype.checkSameEmail = function() 
    { 
     return ((this.text_array.email.value) === (this.text_array.email1.value)); 
    }; 
    Text.prototype.checkEmpty = function() 
    { 
     for (var index = 0; index < this.text_array.length; ++index) 
     { 
      if (this.text_array[ index ].value === '') 
      { 
       return 0; 
      } 
     } 
     return 1; 
    }; 
    return Text; 
}()); 
+1

Es ist kein schlechter Weg, es zu tun – Raynos

+0

Es ist weit von den besten, weil Ihre Globals – Raynos

+0

All diese Dateien sind im globalen Geltungsbereich? 'var Text = ...' – Raynos

Antwort

2

Das einzige, was ich vorschlagen, den Code sauberer und reduzieren ihre Präsenz würde sich ändern ist, um den Prototyp-Eigenschaft auf einmal nur eingestellt, so dass anstatt das zu tun

Object.prototype.method1 = function(){}; 
Object.prototype.method2 = function(){}; 

Sie tun

Object.prototype = { 
    method1: function(){}, 
    method2: function(){} 
}; 

Wenn Sie den Konstruktor Bezug sparen müssen, die recommened ist, können Sie s sollte den Konstruktor danach neu zuweisen. See this answer for more details.

+0

+1. Toller Tipp !!! –

+2

1) "Object.prototype" nie neu zuweisen. 2) Niemals einen Prototyp neu zuweisen, ohne die Eigenschaft 'constructor' zurückzusetzen. – Raynos

+0

@Raynos Kannst du das mehr erklären? –

1

ich persönlich eine modulare Code Organisation Bibliothek lieber mit wie ncore

Dies fördert Sie Ihren Code als eine Reihe von Modulen zu schreiben (ein Modul pro Datei) und haken Sie sie dann mithilfe der Abhängigkeitsinjektion und Bootstrapping zusammen.

Der Code ist leicht portierbar, weil Module nur Objekte selbst sind, aber wenn man keine ncore nutzt, gehen die Vorteile verloren.

Die leaderboard app zeigt ein detailliertes Beispiel der OO-Code Organisation

1

Ein paar Vorschläge ... Zuerst würde ein Namespace-Objekt als Bereich für Ihre Bibliotheken erstellen ... jQuery verwendet "jQuery" und "$", Unterstrich verwendet "_". Ich neige dazu, „CompanyName.SiteName“

if (typeof CompanyName == "undefined") var CompanyName = {}; 
CompanyName.SiteName = CompanyName.SiteName || {};

Die erste Zeile explizit prüft gegen undefinierten zu verwenden, wie Sie Fehler in vielen Browsern anders für die Root-Variablen mit der Methode auf der Site-Name-Eigenschaft erhalten werden.

Von dort würde ich ein paar Anpassungen vornehmen ... Wenn Sie eine anonyme Funktion inline aufrufen, ist es am besten, den gesamten Anruf innerhalb der Parens zu wickeln.

CompanyName.SiteName.ModuleName = (function(w){ 
    ... 
    return moduleImplementation; 
}(window || this)); //CompanyName.SiteName.ModuleName

Dies um die Verwirrung zu vermeiden, neigt dazu, durch die Pars die ganze wickeln ist, und durch am Ende des Moduls Erklärung einen Kommentar zu müssen.

Mit dem obigen Kommentar möchten Sie vielleicht die Prototyp-Deklaration als eine mehr singuläre Aussage machen. Ich würde davon abraten, da längere Module die Lesbarkeit beeinträchtigen können.

myModule.prototype = { 
    "method1": function(){ 
    } 
    ... 
    "methodN": function(){ 
     //by the time you get here, you may not see the top, and where you are nested in 
    } 
}; 

//with the dot-notation, or hash notation 
myModule.prototype.methodN = ... 
myModule.prototype["methodN"] = ... 
//you can see where you are binding to at that function 

Sie können auch sehen wollen in RequireJS und AMD

Es gibt auch das Konzept mit einfacheren Aufgaben fertig zu werden, und mit Hilfe der funktionellen Bindemitteln. Behandeln Sie Ihre Bibliothek als eine Reihe von Funktionen (ähnlich C-Exporte), die übergeben werden und mit einfacheren Objekten/Typen arbeiten. Es hängt wirklich von Ihren Bedürfnissen/Nutzung und den Besonderheiten Ihrer Bedürfnisse und Nutzung ab.

Sie können auch für einige Beispiele Javascript-Bibliotheken wie KnockoutJS, Underscore und Backbone betrachten.

+0

Namespaces sind schlecht. Benutze sie nicht – Raynos

+0

@Raynos Namespaces sind in Ordnung .. sie sind gut für die Code-Isolation. Was ist schlimm, wenn Sie mehrere tief verschachtelte Namespace-Aufrufe machen ... ist es am besten, einen lokalen Variablenalias für Ihren Namespace/Funktion zu erstellen. Aber das ist ein separates Thema für die Modulentwicklung. Es sei denn, Sie verfügen über eine Umgebung, die die Kapselung fördert (z. B. Knoten). – Tracker1

+0

@TheAllFoo Ich sehe Arc nicht als Namespace, ich sehe Arc, Tools und Message. – Tracker1

Verwandte Themen