Nachdem ich einige Nachforschungen zu diesem Thema angestellt habe, habe ich viel mit Mustern experimentiert, um meinen jQuery-Code zu organisieren (Rebecca Murphy hat eine Präsentation auf der jQuery-Konferenz zum Beispiel).
Gestern habe ich das (aufschlussreiche) Modulmuster überprüft. Das Ergebnis erinnert ein wenig an das YUI Syntax, denke ich:
//global namespace MyNameSpace
if(typeof MNS=="undefined"||!MNS){var MNS={};}
//obfuscate module, just serving as a very simple example
MNS.obfuscate = function(){
//function to create an email address from obfuscated '@'
var email = function(){
$('span.email').each(function(){
var emailAddress = $(this).html().replace(' [ @ ] ','@');
$(this).html('<a href="mailto:' + emailAddress + '">' + emailAddress + '</a>');
});
};
return {
email: email
};
}();
//using the module when the dom's ready
jQuery(document).ready(function($){
MNS.obfuscate.email();
});
Am Ende hatte ich mehrere Module. Einige enthielten natürlich "private members", was in diesem Fall bedeutet, dass Variablen und/oder Funktionen, die nur für andere Funktionen innerhalb dieses Moduls von Bedeutung waren, nicht in der Rückgabeanweisung landeten.
Ich dachte, dass es sinnvoll ist, zusammenhängende Teile meines Codes (z.B. alles, was mit der Suche zu tun hat) in einem Modul zusammenzufassen, um dem Ganzen Struktur zu geben.
Aber nachdem ich dies geschrieben hatte, las ich einen Artikel von John (Resig), wo er auch über die Leistung des Modulmusters schreibt:
"Die Instanziierung einer Funktion mit einer Reihe von Prototyp-Eigenschaften ist sehr, sehr schnell. Damit ist das Modul-Muster und Ähnliches völlig überflüssig. Wenn Sie also eine Funktion haben, auf die häufig zugegriffen wird (die ein Objekt zurückgibt) und mit der die Benutzer interagieren sollen, dann ist es von Vorteil, wenn die Objekteigenschaften in der Prototypenkette enthalten sind und die Funktion instanziiert wird. Hier ist es, in Code:
// Very fast
function User(){}
User.prototype = { /* Lots of properties ... */ };
// Very slow
function User(){
return { /* Lots of properties */ };
}
(John erwähnt, dass er nicht gegen das Modulmuster "per se" ist - nur damit Sie es wissen :)
Dann war ich mir nicht mehr sicher, ob ich mit meinem Code in die richtige Richtung ging. Die Sache ist die: Ich weiß nicht wirklich brauchen keine privaten Mitglieder, und ich glaube auch nicht, dass ich vorerst Vererbung brauche. Alles, was ich im Moment will, ist ein lesbares/wartbares Muster. Ich schätze, dass dies bis zu einem gewissen Grad auf persönliche Vorlieben hinausläuft, aber ich möchte nicht mit lesbarem Code enden, der (ziemlich ernste) Leistungsprobleme hat.
Ich bin kein JavaScript-Experte und daher noch weniger ein Experte, wenn es um Leistungstests geht. Zunächst einmal weiß ich also nicht, inwieweit die von John erwähnten Dinge ("häufig genutzte Funktion (die ein Objekt zurückgibt), mit der die Benutzer interagieren sollen", viele Eigenschaften usw.) auf meinen Code zutreffen. Die Dokumente, mit denen mein Code interagiert, sind nicht riesig, mit 100er oder 1000er von Elementen. Vielleicht ist das also gar kein Problem.
Aber eine Sache, die mir in den Sinn gekommen ist, ist, dass man statt nur
$('span.email').each(function(){
var emailAddress = $(this).html().replace(' [ @ ] ','@');
$(this).html('<a href="mailto:' + emailAddress + '">' + emailAddress + '</a>');
});
(innerhalb der domready-Funktion) erstelle ich zwei "zusätzliche" Funktionen, obfuscate und email, aufgrund der Verwendung des Modulmusters. Die Erstellung der zusätzlichen Funktionen kostet etwas Zeit. Die Frage ist: Ist dieser Aufwand in meinem Fall messbar?
Ich bin nicht sicher, ob eine Schließung in meinem Beispiel oben erstellt wird (in einem interessanten Beitrag auf dem jQuery-Forum las ich das folgende: "Es gibt eine philosophische Debatte darüber, ob eine innere Funktion eine Closure erzeugt, wenn sie nichts auf ein variables Objekt einer äußeren Funktion referenziert..."), aber ich hatte Closures in meinem echten Code. Und obwohl ich nicht glaube, dass ich dort irgendwelche zirkulären Referenzen hatte, weiß ich nicht, inwieweit dies zu hohem(er) Speicherverbrauch/Problemen mit der Garbage Collection führen könnte.
Ich würde wirklich gerne Ihren Beitrag dazu hören und vielleicht einige Beispiele Ihres Codes sehen. Und welche Tools bevorzugen Sie, um Informationen über Ausführungszeit, Speicher- und CPU-Auslastung zu erhalten?