Le migliori pratiche OOP Javascript?

Sono stufo di vedere dozzine di modi diversi di fare programmazione orientata agli oggetti in Javascript. Qualcuno può dirmi quale tecnica dovrei usare considerando che voglio lavorare su un progetto su larga scala e voglio che il mio codice sia a prova di futuro?

Queste sono solo alcune linee guida veloci che ho trovato, se qualcun altro ha qualcosa di significativo da aggiungere, ho impostato questa risposta come wiki della comunità, quindi dovrebbe essere abbastanza facile da modificare.

  1. Namespace gli oggetti per assicurarsi che non entrino mai in conflitto con le librerie JavaScript di terze parti.
      window ['Andrew'] ['JS'] = {
         addEvent: function (el, evName) {/ * Stuff * /},
         Rectangle: function (width, height) {/ * Stuff * /}
     }; 

    Quindi, devi creare un object rettangolo usando:

      var myRect = new Andrew.JS.Rectangle (14,11); 

    E quindi il tuo codice non interferirà mai, o sarà interferito da Rectangle qualcun altro.

  2. Utilizzare una strategia di denominazione coerente, in particolare:
    • I nomi degli oggetti dovrebbero essere in maiuscolo, tutto il resto (variabili, funzioni) dovrebbe iniziare con un carattere minuscolo, ad es
        var myRect = new Andrew.JS.Rectangle (14,11);
       document.write (myRect.getArea ()); 
    • Assicurarsi che tutto sia significativo, vale a dire verbi per metodi, nomi + aggettivi per i parametri.
  3. Assicurati che tutti i metodi e i parametri siano pertinenti all’object a cui appartengono. Ad es. In questo esempio, l’area del rettangolo può essere convertita in piedi quadrati usando il metodo inSquareFeet() .

      . MyRect.getAreaObject () inSquareFeet (); 

    Assicurati che inSquareFeet sia un metodo dell’object restituito da getAreaObject() e non un metodo di Andrew.JS.Rectangle

  4. Utilizza i costruttori o, più specificamente, prova il più ansible per assicurarti che un object non abbia bisogno di ulteriori inizializzazioni da utilizzare una volta che è stato costruito, quindi invece di:
      var Person = function ()
     {
         this.name = "";
         this.sayHello = function ()
         {
             alert (this.name + "dice 'Hello!'");
             restituiscilo;
         }
     }
    
     var bob = new Person ();
     bob.name = "Bob Poulton";
     bob.sayHello (); 

    provare:

      var Person = function (nome)
     {
         this.name = nome;
         this.sayHello = function ()
         {
             alert (this.name + "dice 'Hello!'");
             restituiscilo;
         }
     }
    
     var bob = new Person ("Bob Poulton");
     bob.sayHello (); 

Uso sempre John Resig:

http://ejohn.org/blog/simple-javascript-inheritance/

È semplice e non richiede alcun framework per funzionare.

Poiché stai lavorando su un progetto su larga scala suggerirei un framework javascript come mootools http://mootools.net/ .

Ha una buona class e struttura ereditaria.

solo per vostra informazione, penso che YUI fornisca alcuni fantastici tutorial su questo argomento

 //Create and define Global NameSpace Object ( function(GlobalObject, $, undefined) { GlobalObject.Method = function() { /// } GlobalObject.Functionality = {}; }) (GlobalObject = GlobalObject || {}, jQuery); //New object for specific functionality ( function(Events, $, undefined) { //Member Variables var Variable; // (Used for) , (type) // Initialize Events.Init = function() { /// } // public method Events.PublicMethod = function(oParam) { /// /// } // protected method (typically define in global object, but can be made available from here) GlobalObject.Functionality.ProtectedMethod = function() { /// } // internal method (typically define in global object, but can be made available from here) GlobalObject.InternalMethod = function() { /// } // private method var privateMethod = function() { /// } }) (GlobalObject.Funcitonality.Events = GlobalObject.Funcitonality.Events || {}, jQuery ) // Reusable "class" object var oMultiInstanceClass = function() { // Memeber Variables again var oMember = null; // // Public method this.Init = function(oParam) { oMember = oParam; for ( n = 1; i < oMemeber.length; i += 1 ) { new this.SubClass.Init(oMember[i]); // you get the point, yeah? } } this.Subclass = function() { this.Init = function() { } } } 

Il punto di forza di questo è che inizializza automaticamente l'object Global, ti consente di mantenere l'integrità del tuo codice e organizza ogni singola funzionalità in un raggruppamento specifico secondo la tua definizione.

Questa struttura è solida, presentando tutte le cose sintattiche di base che ci si aspetterebbe da OOP senza le parole chiave.

Esistono anche alcuni modi ingegnosi per configurare anche le interfacce. Se si sceglie di andare così lontano, una semplice ricerca ti darà alcuni buoni tutorial e suggerimenti.

Anche la creazione di intellisense è ansible con javascript e visual studio, e quindi definendo ogni pezzo e facendo riferimento a loro rende la scrittura javascript più pulita e più gestibile.

L'utilizzo di questi tre metodi in base alle esigenze della tua situazione aiuta a mantenere pulito lo spazio dei nomi globale, a mantenere il codice organizzato e a mantenere la separazione dei problemi per ciascun object, se usato correttamente. Ricorda, il design orientato agli oggetti è inutile se non usi la logica dietro l'uso degli oggetti!

Il mio object ideale per OOP è come utilizzare un metodo di istanza con prototipi:

Esempio:

 var Users = function() { var _instance; this.prototype.getUsername = function(){/*...*/} this.prototype.getFirstname = function(){/*...*/} this.prototype.getSecurityHash = function(){/*...*/} /*...*/ /*Static Methods as such*/ return { /*Return a small Object*/ GetInstance : function() { if(_instance == null) { _instnance = new Users(arguments); } return _instnance; //Return the object }, New: function() { _instnance = null; //unset It return this.GetInstnace(arguments); } } } 

Quindi vorrei sempre usare come:

 Firstname = Users.GetInstance('Robert','Pitt').getFirstname(); Username = Users.GetInstance().getUsername(); //Returns the above object. Me = Users.New('Robert',null); //Deletes the above object and creates a new instance. Father = Users.New('Peter','Piper'); //New Object Me.AddFather(Father); //Me Object. 

E questo è il tipo di strada che percorro quando si tratta di build un’architettura JavaScript OO Style.

 function foo() { var bar = function() { console.log("i'm a private method"); return 1; }; var iAmAPrivateVariable = 1; return { publicMethod: function() { alert(iAmAPrivateVariable); }, publicVariable: bar() } } //usage var thing = foo() 

Questo è un approccio funzionale e ha molto altro da fare (come l’incapsulamento) quindi qualsiasi altra cosa vedrai

In generale, non dovresti fare OO in javascript, non è un granché per molte ragioni. Pensa a uno schema con parentesi e punti e virgola, e inizierai a scrivere la lingua come fanno i professionisti. Detto questo, a volte OO è una soluzione migliore. In questi casi, quanto sopra è in genere la migliore scommessa

per portare l’ereditarietà nel mix

 function parent() { return { parentVariable: 2 }; } function foo() { var bar = function() { console.log("i'm a private method"); return 1; }; var iAmAPrivateVariable = 1; me = parent(); me.publicMethod = function() { alert(iAmAPrivateVariable); }; me.publicVariable = bar(); return me; } 

Ciò rende le cose un po ‘più complesse, ma realizza il risultato finale desiderato pur mantenendo un approccio funzionale ai concetti OO (in questo caso, utilizzando le funzioni di decoratore invece dell’ereditarietà reale). Quello che mi piace di tutto questo approccio è che stiamo ancora trattando gli oggetti nel modo in cui sono destinati a essere in questo tipo di linguaggio: un sacchetto di proprietà a cui puoi attaccare cose a volontà.

Un’altra nota è che è molto diverso da quello che vedrete il più delle volte nella maggior parte dei lavori a cui lavorerete, e spesso è molto difficile spiegare a) cosa sta succedendo, e b) perché è una buona idea ai colleghi.

Io uso un modello del genere e ti consiglio di usarlo anche:

 function Person(firstname, lastname, age) { var self = this; var _ = {}; // Private members. var firstname = firstname; var lastname = lastname; var age = age || 'unknown'; // Private methods. function first_letter_to_uppercase(str) { return str.charAt(0).toUpperCase() + str.substr(1); } // Public members and methods. _.get_age = function() { return age; } _.get_name = function() { return first_letter_to_uppercase(firstname) + ' ' + first_letter_to_uppercase(lastname); } return _; } var p = new Person('vasya', 'pupkin', 23); alert("It's " + p.get_name() + ', he is ' + p.get_age() + ' years old.') 

Puoi provare con un object semplice, utile e veloce:

 var foo = { foo1: null, foo2: true, foo3: 24, foo4: new Array(), nameOfFunction1: function(){ alert("foo1"); }, nameOfFunction2: function(){ alert("foo2"); }, } 

Per usare questo, devi creare un’istanza di questo object e usarla come un object in java:

 foo.nameOfFunction2(); 

Puoi anche controllare questo link ad altre soluzioni: http://www.javascriptkit.com/javatutors/oopjs.shtml

Spero di rispondere alla tua domanda.