Principiile cheie ale JavaScript de întreținut

JavaScript este o limbă curioasă. Este ușor de scris, dar este greu de stăpânit. Până la sfârșitul acestui articol, sperăm că veți transforma codul de spaghete într-o masă de cinci feluri, plină de minciună ușor de citit și întreținută!


De ce este atat de tare?

Lucrul pe care trebuie să-l amintiți, mai presus de toate atunci când scrieți codul JS, este că este un limbaj dinamic. Asta înseamnă că există mult de moduri de a face lucruri. Nu trebuie să vă ocupați de clase puternic tastate sau de unele dintre caracteristicile mai complexe din limbi, cum ar fi C # și Java. Aceasta este o binecuvântare și un blestem.

"Duritatea" JavaScript-ului este evidentă atunci când se analizează următoarea imagine:

Cartea minusculă din stânga este cartea TREBUIE SĂ CITEȚI Douglas Crockford, JavaScript: piesele bune. Se înalță lângă el, pe dreapta, JavaScript Ghidul definitiv, de David Flanagan.

În timp ce ambele cărți sunt excelente, piesele The Good Parts ilustrează că, deși JavaScript are o mulțime de lucruri în el, părțile bune pot fi rezumate într-o citire considerabil mai scurtă. Deci, dacă căutați o citire bună, rapidă, mergeți cu The Good Parts - și citiți-o de câteva ori!

Acest lucru, firește, a dus la o mulțime de nopți nedormite pentru dezvoltatorii web.

Puteți citi un articol despre istoricul JavaScript aici, dar, în esență, Brandon Eich, în 1995, a fost angajat de Netscape pentru a crea o limbă. Ceea ce a venit a fost limba limpede scrisă pe care o cunoaștem ca JavaScript. De-a lungul anilor, a devenit "standardizat" ca ECMAscript, dar, pe parcursul tuturor războaielor de browser, diferite browsere au implementat aceste caracteristici în mod diferit. Acest lucru, firește, duce la o mulțime de nopți nedormite pentru dezvoltatorii web. Această problemă, combinată cu faptul că JavaScript a fost considerat cel mai aplicabil pentru manipularea imaginilor și efectuarea unor biți rapizi de validare, a determinat ca JavaScript să fie privit incorect ca o teribilă limbă.

E timpul să rezolvăm asta! În timp ce, da, există o mulțime de lucruri rele despre JavaScript, atunci când este folosit corect, poate fi un limbaj fantastic - și natura lui dinamică va crește pe tine!


A face mai bine

Spații de nume

Unul dintre downfalls de modul în care este implementat JavaScript este că operează pe o global obiect. În cazul browserelor, acest lucru va rezulta fiind fereastră obiect. Deci, oricând acest cod este prezent pe o pagină ...

 funcția doStuff () alertă ("Fac lucruri");  funcția doMoreStuff () var images = document.images.length; console.log ("În această pagină sunt" + imagini + ");  doStuff (); doMoreStuff ();

Funcțiile doStuff si doMoreStuff funcțiile sunt disponibile imediat la nivel global fereastră obiect.

Aceasta înseamnă că dacă vine cineva și încearcă să scrie o funcție, care este de asemenea numită, doStuff, va exista un conflict! Toate scenariu în mod normal, etichetele iau codul în interiorul lor și îl execută împotriva fereastră în ordinea în care sunt menționate în HTML. Ca rezultat, a doua persoană să pună în aplicare doStuff va suprascrie prima doStuff.

O tehnică comună pentru eliminarea acestei probleme este de a profita de funcțiile anonime sau de spațiile de nume. Oamenii orientați spre obiect care citesc acest lucru sunt probabil deja familiarizați cu conceptul unui spațiu de nume, dar ideea de bază este de a grupa funcții în diferite domenii pentru reutilizare.

 var NS = NS || ; // "Dacă NS nu este definită, o face egală cu un obiect gol" NS.Utils = NS.Utils || ; NS.Models = NS.Models || ; NS.Views = NS.Views || ;

Acest lucru va preveni poluarea spațiului de nume global și va ajuta la lizibilitatea aplicației dvs. Acum, pur și simplu definiți funcții în spațiul lor de nume respectiv. Un spațiu de nume definit în mod obișnuit este aplicaţia, care gestionează restul aplicației.

Modele și practici de proiectare

În fiecare limbă, există un set de modele de design. Addy Osmani spune ...

Modelele de proiectare sunt soluții reutilizabile pentru problemele întâlnite în mod obișnuit în proiectarea software-ului.

Există loturi și, atunci când sunt folosite corect, pot afecta în mod semnificativ întreținerea aplicației. Addy a scris o carte excelentă de modele de design JavaScript, numită modele esențiale de design. Absolute da-i o citire!

Un alt model utilizat în mod obișnuit este modelul Descoperirea modelului de model.

 NS.App = (functie () // Initializeaza aplicatia var init = function () NS.Utils.log ('Initialized application ...'); init; ()); NS.App.init ();

Deasupra, un App funcția este definită în cadrul NS obiect. În interior, o variabilă de funcție pentru init este definit și returnat ca un obiect anonim literal. Observați că, la sfârșit, există setul suplimentar de paranteze: ());. Aceasta forțează NS.App funcția de a executa automat și de a reveni. Acum poți suna NS.App.init () pentru a inițializa aplicația.

Funcția anonimă de mai sus este o bună practică în JavaScript, și este denumită a Funcția anonimă care se execută automat. Deoarece funcțiile din JavaScript au propriul scop - adică variabilele definite în interiorul funcțiilor nu sunt disponibile în afara lor - aceasta face ca funcțiile anonime să fie utile în mai multe moduri.

 // Wrap codul intr-un SEAF (functie (globala) // Acum orice variabile pe care le declarati aici nu sunt disponibile in afara. Var somethingPrivate = 'tu cant sa ajungi la mine!'; Global.somethingPublic = 'dar poti ajunge la mine! '; (fereastră)); console.log (window.somethingPublic); // Aceasta funcționează ... console.log (somethingPrivate); // Eroare

În acest exemplu, deoarece această funcție este executată automat, puteți trece fereastră în partea de executare (fereastră));, și va fi disponibil ca global în interiorul funcției anonime. Această practică limitează variabilele globale pe fereastră obiect și va ajuta la prevenirea coliziunilor de numire.

Acum, puteți începe să utilizați SEAF-urile în alte zone ale aplicației dvs. pentru a face codul să se simtă mai modular. Acest lucru permite ca codul dvs. să fie reutilizabil și promovează o bună separare a preocupărilor.

Iată un exemplu de utilizare potențială a acestor idei.

 (funcția ($) var welcomeMessage = 'Bine ați venit la această aplicație!' NS.Views.WelcomeScreen = function () this.welcome = $ ('welcome); : function () this.welcome.html (welcomeMessage) .show ();; (jQuery)); $ (funcție () NS.App.init ();); // Modificați App.init deasupra var init = function () NS.Utils.log ('Aplicație inițializată ...'); this.welcome = nou NS.Views.WelcomeScreen (); this.welcome.showWelcome (); ;

Deci, mai sus, există câteva lucruri diferite care se întâmplă. in primul rand, jQuery este trecut ca un argument pentru funcția anonimă. Acest lucru asigură că $ este de fapt jQuery în interiorul funcției anonime.

Apoi, există o variabilă privată, numită mesaj de intampinare, și o funcție este atribuită NS.Views.WelcomeScreen. În interiorul acestei funcții, this.welcome este atribuit unui selector jQuery DOM. Aceasta stochează selectorul din interior welcomeScreen, astfel încât jQuery nu trebuie să interogheze DOM de mai multe ori.

Interogările DOM pot fi intensive, așa că asigurați-vă că le stocați cât mai mult posibil.

Apoi, împachetăm aplicația init în $ (Funcția () );, care este același lucru ca și cum faceți $ (Document) .ready ().

În final, adăugăm un cod la inițializatorul aplicației. Acest lucru vă păstrează codul frumos și separat și va fi considerabil ușor să reveniți și să vă modificați într-o zi ulterioară. Mai multă mentenabilitate!

Modelul de observator

Un alt model excelent este Modelul de Observer - denumit uneori "Pubsub". Pubsub ne permite, în esență, să ne abonați la evenimentele DOM, cum ar fi clic și mouse-ul peste. Pe de o parte, suntem ascultare la aceste evenimente și, pe de altă parte, ceva publică acele evenimente - de exemplu, când browserul publică (sau anunță) că cineva a dat clic pe un anumit element. Există multe biblioteci pentru pubsub, deoarece este un pic de cod. Efectuați o căutare rapidă pe Google și mii de opțiuni se vor pune la dispoziție. O alegere solidă este implementarea lui AmplifyJS.

 // Un model de date pentru extragerea de știri. NS.Models.News = (functie () var newsUrl = '/ news /' // Recuperare stiri var getNews = function () $ .ajax (url: newsUrl type: 'get', succes: newsRetrieved) ; var varRetrieved = funcția (știri) // Publicați recuperarea știrilor amplify.publish ('news-retrieved', news); return getNews: getNews;

Acest cod definește un model pentru a obține știri de la un fel de serviciu. Odată ce știrea a fost extrasă cu AJAX, newsRetrieved metode de incendiu, trecând prin știrile preluate către Amplify, și este publicat pe tema preluată de știri.

 (funcția () // Crearea unei vederi de știri NS.Views.News = funcția () this.news = $ ('news'); // Abonați-vă la evenimentul de recuperare a știrilor amplify.subscribe (' (de exemplu), $ .proxy (this.showNews)); // Afișați știrile când sosesc NS.Views.News.prototype.showNews = Funcție (știri) var self = this; (articolul) self.append (articolul);); ());

Acest cod de mai sus este o vizualizare pentru afișarea știrilor preluate. În Știri constructor, Amplify subscrie la subiectul preluat de știri. Atunci când acel subiect este publicat, showNews funcția este declanșată, în consecință. Apoi, știrile sunt atașate DOM.

 // Modificați acest lucru App.init deasupra var init = function () NS.Utils.log ('Aplicație inițializată ...'); this.welcome = nou NS.Views.WelcomeScreen (); this.welcome.showWelcome (); this.news = noi NS.Views.News (); // Du-te de știri! NS.Models.News.getNews (); ;

Din nou, modificați init funcția de la aplicație pentru a adăuga recuperarea știrilor ... și ați terminat! Acum, există părți separate ale aplicației, fiecare dintre acestea fiind responsabilă de o singură acțiune. Acesta este cunoscut sub numele de Principiul unic de responsabilitate.


Documentație și Dosare / Minificare

Una dintre cheile unui cod de întreținere de orice fel - nu doar JS - este documentare și comentarii. Comentariile pot servi ca fiind valoroase pentru noii dezvoltatori care intră într-un proiect - trebuie să înțeleagă ce se întâmplă în cod. "De ce am mai scris din nou acea linie?". Un instrument excelent pentru generarea documentației este numit Docco. Acesta este același instrument care generează documentația pentru site-ul Web Backbone.js. Practic, este nevoie de comentariile dvs. și le plasează alături de codul dvs..

Există, de asemenea, unelte, cum ar fi JSDoc, care generează o documentație de stil API, care descrie fiecare clasă din codul dvs..

Un alt lucru, care se poate dovedi a fi dificil când începeți un nou proiect, încearcă să determinați cum să vă organizați cel mai bine codul. O modalitate este de a separa bucăți de funcționalitate în foldere separate. De exemplu:

  • /app.js
  • /libs/jquery.js
  • /libs/jquery-ui.js
  • /users/user.js
  • /views/home.js

Această structură ajută la păstrarea pieselor de funcționalitate în afară unul de celălalt. Există, desigur, mai multe moduri de a organiza codul, dar tot ce contează este decizia unei structuri ... și apoi rularea cu ea. Apoi, puteți utiliza un instrument de construire și minificare. Există o mulțime de opțiuni:

  • mormăit
  • Închiderea Google
  • JSMin
  • Compresor YUI

Aceste instrumente vor elimina spațiul alb, vor elimina comentariile și vor combina toate fișierele specificate într-una. Aceasta reduce dimensiunile fișierelor și cererile HTTP pentru aplicație. Chiar mai bine, aceasta înseamnă că puteți păstra toate fișierele separate în timpul dezvoltării, dar combinate pentru producție.


AMD

Modulul asincron de definire este un mod diferit de scriere a codului JavaScript.

Modulul asincron de definire este un mod diferit de scriere a codului JavaScript; acesta împarte întregul cod în module separate. AMD creează un model standard pentru scrierea acestor module pentru încărcarea în cod asincron.

Utilizarea scenariu tag-urile blochează pagina, în timp ce se încarcă până când DOM-ul este gata. Prin urmare, utilizarea unui AMD va permite DOMului să continue încărcarea, în timp ce script-urile se încarcă încă. În esență, fiecare modul este împărțit în propriul fișier, iar apoi există un fișier care începe procesul. Cea mai populară implementare a AMD este RequireJS.

 // main.js necesită (['libs / jquery', 'app.js'], funcția ($, app) $ (function () app.init (););); // app.js define (['libs / jquery', 'views / home']], funcția ($, home) home.showWelcome ();); // home.js define (['libs / jquery'], funcția ($) var home = function () this.home = $ (' this.home.html ('Bine ați venit!');; întoarceți noul domiciliu (););

În fragmentul de cod de mai sus, există a main.js fișierul, unde începe procesul. Primul argument adresat necesita funcția este o serie de dependențe. Aceste dependențe reprezintă o listă de fișiere pentru care este necesar app.js. Pe măsură ce termină încărcarea, indiferent de modul în care se întoarce modulul, este trecut ca argument la apelul funcțional din dreapta.

Apoi, există app.js, care necesită jQuery, precum și o vedere. Apoi, vizualizarea, home.js, solicită doar jQuery. Are o Acasă funcționează în cadrul acesteia și returnează o instanță a ei înșiși. În aplicația dvs., aceste module sunt stocate în fișiere separate, ceea ce face ca aplicația dvs. să fie foarte ușor de întreținut.


Concluzie

Menținerea aplicabilității aplicațiilor dvs. este extrem de importantă pentru dezvoltare. Ea reduce bug-urile și face procesul de fixare a celor pe care le găsiți mai ușor.

"Prietenii nu lasă prietenii să scrie spaghetti cod!"

Cod