1. Folosiți-o corect atunci când lucrați cu dispozitive de închidere
Aceasta duce la o eroare:
De ce se întâmplă acest lucru? Totul este în context. Când apelați setTimeout (), suni de fapt window.setTimeout (). Ca rezultat, funcția anonimă trecuta la setTimeout () este definită în contextul obiectului fereastră, care nu are metoda clearBoard ().
O soluție tradițională care este compatibilă cu browserele mai vechi implică pur și simplu stocarea unei referințe la aceasta într-o variabilă care poate fi stocată într-o închidere:
Pentru browserele noi, puteți utiliza metoda bind (), care vă permite să asociați o funcție cu contextul de execuție:
3. Pierderi de memorie
Pierderile de memorie sunt aproape inevitabile, dacă în timpul muncii nu le veți evita în mod conștient. Există multe motive pentru apariția unor scurgeri, însă ne vom concentra doar pe cele mai frecvente.
Legături către obiecte inexistente
Să analizăm acest cod:
Dacă executați codul de execuție, puteți detecta o scurgere masivă de memorie cu o viteză de aproximativ megabytes pe secundă. Se pare că vom pierde memoria alocată sub longStr de fiecare dată când se numește replaceThing. Care este motivul?
Un mod tipic de a pune în aplicare vina - este de a crea o conexiune între fiecare obiect funcție și dicționarul obiect, care este un domeniu de aplicare lexicală pentru această funcție. Dacă ambele funcții (neutilizate și SomeMethod), anumite vnutrireplaceThing utilizate efectiv priorThing, este important să se înțeleagă că acestea sunt unul și același obiect, chiar dacă priorThing rescris din nou și din nou, deoarece ambele funcții utilizează același domeniu de aplicare lexicală. Și de îndată ce variabila este folosită în oricare dintre dispozitivele de închidere, ea intră în domeniul de aplicare lexic utilizat de toate închiderile din acest domeniu. Și această mică nuanță duce la o scurgere de memorie puternică.
Link-uri ciclice
Luați în considerare exemplul de cod:
- referințele la care sunt conținute în stiva de apeluri (toate variabilele locale și parametrii de funcții care sunt în prezent apelați, precum și toate variabilele din domeniul de închidere);
- toate variabilele globale.
Obiectele sunt stocate în memorie numai atâta timp cât sunt accesibile din rădăcină prin referință sau printr-un lanț de link-uri.
În browsere este încorporat un colector de gunoi, care șterge memoria de la obiecte inaccesibile. Adică, obiectul va fi șters din memorie numai dacă colectorul de gunoi decide că acesta nu este accesibil. Din păcate, obiectele mari neutilizate care sunt considerate "realizabile" se pot acumula destul de ușor.
4. Neînțelegerea egalității
După cum arată cele două exemple de mai sus, conversia de tip automat poate interfera uneori. De regulă, este mai bine să utilizați === și! == în loc de == și! =, Pentru a evita efectele secundare ale conversiei de tip.
Apropo, compararea NaN cu ceva (chiar și cu NaN!) Întotdeauna produce rezultate false. Astfel, nu puteți utiliza operatorii de egalitate (==, ===. =. ==) pentru a determina conformitatea NaN. În schimb, trebuie să utilizați funcția globală isNaN () încorporată:
5. Folosiți corect DOM
Dacă doriți să adăugați mai mult de un element, atunci, alternativ, puteți utiliza fragmentele de document:
6. Utilizarea corectă a definițiilor funcțiilor în cadrul buclelor for
Luați în considerare exemplul de cod:
Când faceți clic pe oricare dintre cele 10 elemente, va apărea mesajul "Acesta este elementul # 10". Motivul este că, în momentul în care onclick-ul este apelat de oricare dintre elementele, bucla pentru se va termina și valoarea lui i va fi 10.
Exemplu de cod corect:
makeHandler începe imediat la fiecare iterație a buclă, devine valoarea curentă a lui i + 1 și o stochează în variabila num. Funcția externă returnează o funcție internă (care folosește de asemenea variabila num) și o fixează ca pe un handler onclick. Acest lucru face posibilă asigurarea faptului că fiecare onclick primește și utilizează valoarea corectă a i.
7. Moștenirea corespunzătoare prin prototipuri
În mod surprinzător, mulți dezvoltatori nu au o înțelegere clară a mecanismului de moștenire prin prototipuri. Luați în considerare exemplul de cod:
Dar dacă am scris astfel:
Dar nu este mai bine să returnezi o valoare implicită? Acest lucru se poate face cu ușurință prin aplicarea moștenirii prin prototipuri:
Fiecare instanță a BaseObject moștenește proprietatea nume a prototipului său, în care este setată implicit. Astfel, dacă constructorul este apelat fără nume, proprietatea implicită este implicită. În mod similar, în cazul în care numele proprietății va fi șters din exemplu BaseObject, căutarea se realizează pe namebudet lanțului de prototip și a bunurilor obținute de prototip obiect, în care este încă egală cu valoarea implicită:
8. Creați referințe corecte la metode de instanță
Definiți un constructor simplu și îl utilizați pentru a crea un obiect:
Pentru comoditate, vom crea un link la metoda whoAmI:
Să afișăm valoarea variabilei noi whoAmI:
Consola va afișa:
Și acum acordați atenție diferenței dintre apelurile către obj.whoAmI () și whoAmI ():
Ce sa întâmplat? Când am atribuit var whoAmI = obj.whoAmI; noua variabilă a fost definită în spațiul de nume global. Ca rezultat, acest lucru sa dovedit a fi egal cu fereastra, nu obj, cu instanța MyObject. Astfel, dacă într-adevăr trebuie să creați o referință la o metodă obiect existentă, trebuie să facem acest lucru în spațiul de nume al acestui obiect. De exemplu:
9. Folosirea unui șir ca prim argument în setTimeout sau setInterval
Acest lucru nu este o greșeală în sine. Și nu este vorba doar de performanță. Faptul este că atunci când treceți o variabilă de șir la primul argument în setTimeout sau setInterval, acesta va fi transmis constructorului de funcții pentru a converti la o nouă funcție. Acest proces poate fi lent și ineficient. O alternativă este utilizarea funcției ca prim argument:
10. Refuzul de a utiliza "modul strict"
Acesta este un mod în care se impun o serie de restricții privind codul executabil, ceea ce sporește securitatea și poate preveni apariția unor erori. Desigur, refuzul de a folosi "regimul strict" nu este o eroare per se. Pur și simplu în acest caz, vă lipsiți de mai multe avantaje: