Top 10 lucruri pe care JavaScript le-a greșit

JavaScript, dacă este doar în mod implicit, este una dintre cele mai populare limbi de programare disponibile. De-a lungul anilor, a fost etichetat ca un coșmar pentru a lucra și, într-o anumită măsură, acest lucru este adevărat! Cu toate acestea, de cele mai multe ori, ceea ce vrea să spună este că DOM API este un coșmar. Cu toate acestea, există o mulțime de erori flat-out în limba.

Aș dori să fac o notă că îmi place JavaScript. Acest articol este destinat doar pentru o distracție și pentru noi să fim conștienți de unele neajunsuri.

1. Numele. JavaScript nu este Java

Vom începe cu o distracție plăcută la alegerea numelui. În timp ce a fost inițial numit Mocha, și apoi LiveScript, a fost ulterior modificat la JavaScript. Potrivit istoriei, asemănările sale cu numele Java au fost rezultatul unei colaborări între Netscape și Sun, în schimbul îmbinării Netscape a runtime-ului Java în browser-ul lor popular. De asemenea, sa remarcat faptul că numele a apărut, aproape ca o glumă, din cauza rivalității dintre LiveScript și Java pentru scripting pe partea clientului.

Cu toate acestea, aceasta a dus la mii de comentarii "JavaScript nu are nimic de-a face cu Java" în forumuri de pe web!

2. Null este un obiect?

Gandeste-te la asta…

 console.log (typeof null); // obiect

Acest lucru face ca zero sens. Dacă nul este absența unei valori, atunci cum ar putea fi tipul ei "obiect?" Răspunsul simplu este că este o eroare de tip flat-out care datează de la prima lansare a JavaScript - una care a fost chiar transmisă incorect în JScript-ul Microsoft.

3. NaN = NaN

NaN, așa cum ne-am fi așteptat, se referă la o valoare care nu este un număr legal. Problema este că NaN nu este egal cu nimic ... inclusiv cu el însuși.

 console.log (NaN === NaN); // fals

Acest lucru ar trebui să fie greșit. În schimb, dacă doriți să determinați dacă o valoare este într-adevăr NaN, puteți utiliza funcția isNaN ().

Actualizați: după ce a citit câteva dintre comentariile strălucite, în special cele referitoare la NaN fiind similar cu infinitul, atunci are sens perfect că NaN nu ar fi egal. Dar poate fi încă confuz. Consultați comentariile pentru o discuție aprofundată în acest sens!

4. Variabilele globale

Dependența de variabilele globale este considerată pe scară largă a fi cea mai proastă parte a JavaScript. Pentru proiectele simple, la fel ca sfaturile rapide pe acest site, aceasta nu face cu adevărat o diferență. Cu toate acestea, povara reală a globalelor intră în joc atunci când începeți să faceți referire la mai multe scenarii, fără să știți cum sunt create sau numite. Dacă se întâmplă să împartă același nume cu una dintre variabilele dvs., programul dvs. va arunca un fel de eroare.

"Problema cu JavaScript nu este doar faptul că le permite (variabile globale), le cere." - Crockford

5. Raportul utilizator-agent Strings raport Mozilla. Erați minunat De ce?

Bine - aceasta nu este vina JavaScript. Am inselat un pic. Este din cauza furnizorilor de browsere. Acestea fiind spuse, detectarea șirului utilizator-agent este foarte frecventă în JavaScript; așa că este important să știți ce aveți de-a face. Probabil că nu aparține acestei liste, dar care îi pasă! Este bine să știi.

Aceasta nu este o greșeală atât de mare încât a fost o decizie inevitabilă. De exemplu, deschideți Safari, accesați Inspectorul Web și înregistrați șirul de agent utilizator în consola.

 console.log (navigator.userAgent); // Mozilla / 5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit / 531.21.8 (KHTML, ca Gecko) Versiunea / 4.0.4 Safari / 531.21.10

Rețineți că primul șir de caractere: Mozilla / 5.0. De ce ar fi identificat Safari browserul bazat pe Mozilla? Deși mai târziu se identifică corect, ea nu explică încă de ce se deranjează să inducă în eroare programatorii. De fapt, veți descoperi că majoritatea browserelor se identifică ca Mozilla. Răspunsul durează un deceniu și, din nou, este mai puțin o eroare și mai mult o circumstanță inevitabilă.

Pentru cei necunoscuți, un șir de utilizator-agent este menit să identifice browserul și versiunea acestuia. De exemplu, primul browser, Mosaic, a avut un șir de utilizator-agent care arăta astfel:

 Mozaic / 0.9 // numele browserului / numărul versiunii

Acest lucru are sens perfect. Iar când Netscape a venit pe scenă, ei au păstrat utilizarea lui Mosaic și, de asemenea, au adăugat o secțiune de tip criptare.

 Mozilla / 2.02 [en] (Win95; I) // numele browserului / versiunea / criptarea

Până acum, bine. Problemele au intrat în joc când - așteptați - Internet Explorer 3 a fost lansat. Rețineți că, atunci când au lansat, Netscape a fost cel mai popular browser disponibil. De fapt, multe servere și programe au implementat deja detectarea utilizatorilor-agenți pentru a identifica Netscape. Deși acesta este un subiect foarte dezbătut astăzi, atunci nu a fost o problemă prea mare. Dacă IE ar fi folosit propriul șir de utilizator-agent, ar fi arătat ceva de genul:

 MSIE / 3.0 (Win95; U)

Acest lucru i-ar fi lăsat într-un dezavantaj imens, deoarece Netscape era deja identificat de mai multe servere. Ca atare, dezvoltatorii au decis să identifice incorect browser-ul ca Mozilla și apoi să adauge un set suplimentar de informații care îl etichetează ca Internet Explorer.

 Mozilla / 2.0 (compatibil; MSIE 3.0; Windows 95)

În zilele noastre, detecția agentului de utilizator este un ultim efort și este considerat atât de precis din acest motiv. Veți găsi că majoritatea browserelor au urmat conducerea IE în identificarea ei ca fiind Mozilla. Gândiți-vă la aceasta ca la o reacție în lanț.

Citirea în continuare

Vă recomandăm foarte mult să citiți "Istoricul String-ului User-Agent" al lui Nicholas Zakas, dacă doriți să vă însuflați mai adânc.

6. Inconsecvențele de domeniu

Luați în considerare următorul cod:

 // Creați o funcție care va apela o funcție cu numele egal cu parametrul fn. funcția foo (fn) if (typeof fn === "funcția") fn ();  // Creați un obiect cu o proprietate și o metodă. var bar = barbar: "Bună ziua, Lumea!", metoda: function () alert (this.barbar); ; bar.method (); // Alerte Bună ziua, lume! foo (bar.method); // Dacă apelam funcția foo, adăugați metoda "bar.method", avertizează cumva "undefined". foo (funcție () bar.method ();); // alerte Buna, Lumea, după

Motivul pentru care foo (bar.method) nu face același rezultat se datorează faptului că funcția metodei va fi apelată ca metodă a obiectului ferestrei, mai degrabă decât bara. Pentru a rezolva acest lucru, trebuie să apelăm bar.method () din cadrul funcției anonime trecute.

Mulțumesc foarte mult lui Jeremy McPeak pentru că mi-a anunțat această eroare.

7. Utilizarea operatorilor cu biți

JavaScript are multe asemănări cu Java - unul dintre ele fiind setul de operatori de biți.

  • & - și
  • | - sau
  • ^ - XOR
  • ~ - nu
  • >> - semnează schimbarea corectă
  • ??? - nesemnate schimbare dreapta
  • << - schimbare stânga

Luați în considerare primul element, &; ar fi mult mai eficient să folosim operatorul &&, deoarece este mai rapid. Acest lucru se datorează faptului că JavaScript nu este același cu Java și nu are numere întregi. Ca atare, este necesar un proces de lungime relativă pentru a converti operandul, pentru a face ceva cu el și apoi pentru ao converti.

Acesta este motivul pentru care puteți scăpa cu utilizarea & pentru "și", și | pentru "sau" - chiar dacă ar trebui să utilizați && și ||.

8. Prea multe valori Falsy / Bottom

Poate că aceasta nu este o eroare specifică în JavaScript, dar cu siguranță face ca procesul de învățare, în special pentru începători, să fie unul greu. Valori precum nul, fals și nedefinit înseamnă aproape același lucru, dar există diferențe care pot fi confuze pentru a le înțelege.

Valorile Falsy

Pentru a testa, deschideți consola din Firefox și găsiți booleana următoarelor elemente.

 !!(0); // false !! (false); // false (); // false !! (null); // false !! (undefined); // false !! (NaN); // false

Rețineți că orice alte valori vor fi interpretate ca trut.

Mai mult decât o eroare, aceste multe valori false sunt doar confuze!

9. Nu poate face aritmetică

Bine, bine - eu sunt 99% teasing cu titlul de mai sus. Dar JavaScript are câteva probleme minore atunci când lucrează cu zecimale, de exemplu, lucruri ca tranzacțiile cu bani. De exemplu, deschideți consola și înregistrați ".2 + .4". Ne-am aștepta să afișeze ".6", corect? Ei bine, și nu!

 console.log (.2 + .4); // 0.6000000000000001

Cum se face? La un nivel ridicat, se datorează faptului că JavaScript a folosit standardul IEEE pentru aritmetica cu binare în virgulă plutitoare. Probabil că vă plac, nu înțelegeți cu exactitate exact ceea ce specifică, ci doar știți că, atunci când se ocupă de fracții zecimale, rezultatele pot varia ușor față de ceea ce vă puteți aștepta. Rețineți că aritmetica întregului este perfectă, deci într-adevăr aceasta nu este o problemă uriașă.

10. Stylingul codului nu este alegerea ta!

Când vine vorba de stilul tău de codificare, este exact că: stilul tau. Unii oameni preferă să-și plaseze coatele ondulate pe aceeași linie cu controlul, alții preferă să meargă pe cont propriu.

 // brațele din dreapta retur foo: bar; // brațele pe propria linie întoarcă foo: bar;

În funcție de prima carte Web dev, pe care o citim sau cum ne-a învățat profesorul, este perfect acceptabil să folosiți oricare dintre metodele de mai sus sau chiar o combinație a celor două. Problema cu JavaScript este că nu este alegerea ta!

Am învățat acest exemplu special dintr-o prelegere pe care Doug Crockford a dat-o în urmă cu aproximativ un an. Luați în considerare declarația de returnare de mai sus. Credeți sau nu, ei NU sunt egali. Nu mă credeți? Încearcă asta. Adăugați următoarele la o pagină HTML.

 var foo = funcție () retur a: 'b';  (); alert (foo.a); // b

Codul de mai sus creează pur și simplu o variabilă numită foo, care este egală cu obiectul returnat. Atunci când alertăm (foo.a), vom vedea, după cum era de așteptat, o casetă de avertizare cu o valoare de "b". Acum, pur și simplu luați acea bretonă de deschidere, din declarația de întoarcere, și împingeți-o pe linia proprie, ca atare.

 retur a: 'b';

Dacă îl rulați din nou în browser, veți primi o eroare Firebug, înregistrând că "foo este nedefinită". Ce naiba!? :)

Deci, de ce JavaScript face acest lucru? Este din cauza a ceva numit "inserție punct și virgulă". În esență, JavaScript va încerca să corecteze codurile noastre proaste. Dacă, de exemplu, credeți că ați oprit o punct și virgulă de închidere, va merge mai departe și adăugați-o pentru voi. Deși acest lucru a fost intenționat inițial pentru a fi o convenție, mai ales pentru noii JavaScript-uri, este într-adevăr un lucru foarte rău când nu aveți control asupra propriului cod, așa cum sa demonstrat mai sus.

În exemplul nostru, nu există nici o modalitate de a determina de ce foo.a se întoarce "undefined". Acum că suntem conștienți de inserția punctului de mijloc, motivul pentru care este nedefinit este că JavaScript va adăuga un punct și virgulă la sfârșitul instrucțiunii returnate.

 întoarcere; // JS adaugă incorect acest punct și virgulă. a: "b"; // Se va adăuga și aici punct și virgulă, deoarece nu înțelege că acesta este un obiect. ;

Deci, dacă ne întoarcem imediat, nu are nicio idee ce înseamnă proprietatea "a", rezultând astfel "nedefinită".

Concluzie

După cum am menționat la începutul acestui articol, îmi place JavaScript și îl folosesc zilnic. Dar asta nu înseamnă că nu există vreo greșeală cu adevărat îngrozitoare în limbaj. Mi-ar plăcea să vă aud gândurile în comentariile! Vă mulțumim pentru lectură. Retweets și Diggs sunt întotdeauna apreciate! Mulțumesc mult lui Jeremy McPeak, lui Doug Crockford, lui Nicholas Zakas și lui John Resig: M-am referit la tutoriale și cărți când pregăteam acest articol.

  • Urmați-ne pe Twitter sau abonați la Nettuts + RSS Feed pentru cele mai bune tutoriale de dezvoltare web de pe web.
Cod