Topp 10 ting som JavaScript ble feil

JavaScript, hvis bare som standard, er et av de mest populære programmeringsspråkene som er tilgjengelige. Gjennom årene har det blitt merket som et mareritt å jobbe med, og til en viss grad er dette sant! Men oftere enn ikke, hva folk mener å si er at DOM API er et mareritt. Likevel er det en håndfull flat-out-feil på språket.

Jeg vil gjerne notere at jeg elsker JavaScript. Denne artikkelen er bare ment for litt moro, og for oss å være klar over noen av sine kortkomninger.

1. Navnet. JavaScript er IKKE Java

Vi starter med en morsom jab ved navnevalget. Mens det opprinnelig ble kalt Mocha, og deretter LiveScript, ble det senere endret til JavaScript. Ifølge historien var dens likheter med navnet Java resultatet av et samarbeid mellom Netscape og Sun, i motsetning til Netscape som bunter Java-kjøretiden i sin populære nettleser. Det er også lagt merke til at navnet kom, nesten som en vits, på grunn av rivaliteten mellom LiveScript og Java for script-side scripting.

Likevel resulterte det i tusenvis av "JavaScript har ingenting å gjøre med Java" kommentarer i fora på nettet!

2. Null er et objekt?

Vurder dette ...

 console.log (type null); // objekt

Dette gir nullfølelse. Hvis null er fraværet av en verdi, så hvordan kan dens type være "objekt?" Det enkle svaret er at det er flat-out en feil som går tilbake til den første versjonen av JavaScript - en som selv ble feil overført til Microsofts JScript.

3. NaN! == NaN

NaN, som vi forventer, refererer til en verdi som ikke er et juridisk nummer. Problemet er at NaN ikke er lik noe ... inkludert seg selv.

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

Dette burde være feil. I stedet, hvis du vil avgjøre om en verdi er faktisk NaN, kan du bruke funksjonen isNaN ().

Oppdater: etter å ha lest gjennom noen av de strålende kommentarene, spesielt de som relaterer seg til NaN, ligner uendelig, så er det perfekt fornuftig at NaN ikke ville være like. Men det kan fortsatt være forvirrende. Se kommentarene for en grundig diskusjon om dette!

4. Globale variabler

Avhengigheten av globale variabler anses allment som den verste delen av JavaScript. For enkle prosjekter, i likhet med de raske tipsene på dette nettstedet, gjør det egentlig ingen rolle. Den virkelige byrden til globals kommer imidlertid inn i spill når du begynner å referere til flere skript uten å ha kjennskap til hvordan de er opprettet eller navngitt. Hvis de tilfeldigvis deler samme navn som en av variablene dine, kommer programmet ditt til å kaste en slags feil.

"Problemet med JavaScript er ikke bare at det tillater dem (globale variabler), det krever dem." - Crockford

5. Bruker-Agent Strings Rapporter Mozilla. Noen gang lurer på hvorfor?

Ok, dette er ikke feilen til JavaScript. Jeg lurte litt. Det er på grunn av nettleservirksomhetene. Når det er sagt, er det viktig at bruker-agent-strengdeteksjon er i JavaScript; så det er viktig å vite hva du har å gjøre med. Det tilhører trolig ikke i denne listen, men hvem bryr seg! Det er godt å vite.

Denne er ikke så mye en feil da det var en uunngåelig beslutning. For eksempel, åpne Safari, få tilgang til webinspektøren, og logg brukeragentstrengen inn i konsollen.

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

Legg merke til at første streng av tegn: Mozilla / 5.0. Hvorfor skulle Safari identifisere det som en Mozilla-basert nettleser? Selv om det senere identifiserer seg selv, forklarer det fortsatt ikke hvorfor de ville plage å villede programmerere. Faktisk finner du at de fleste nettlesere identifiserer seg som Mozilla. Svaret går tilbake et tiår, og er igjen, mindre en feil, og mer en uunngåelig omstendighet.

For de ukjente er en bruker-agent-streng bare ment å identifisere nettleseren og dens versjon. Som et eksempel hadde den første nettleseren, Mosaic, en bruker-agent-streng som så ut som:

 Mosaic / 0.9 // nettlesernavn / versjonsnummer

Dette gir perfekt mening. Og da Netscape kom på scenen, holdt de Mosaic's bruk, og også lagt til en krypteringstype seksjon.

 Mozilla / 2.02 [en] (Win95; I) // nettlesernavn / versjon / kryptering

Så langt så bra. Problemene kom til spill når - vent på det - Internet Explorer 3 ble utgitt. Husk at når de startet, var Netscape den mest populære nettleseren tilgjengelig. Faktisk implementerte mange servere og programmer allerede brukeragent deteksjon for å identifisere Netscape. Selv om dette er et høyt debattert emne i dag, da var det ikke mye av et problem. Hvis IE hadde brukt sin egen user-agent-streng, ville det ha sett noe ut som dette:

 MSIE / 3.0 (Win95; U)

Dette ville ha etterlatt dem i stor ulempe, fordi Netscape allerede ble identifisert av mange servere. Som sådan bestemte utviklerne seg for feilaktig å identifisere nettleseren som Mozilla, og deretter legge til et ekstra sett med informasjonsmerking som Internet Explorer.

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

I dag er brukeragent deteksjon en siste innsats, og det er vurdert så nøyaktig av denne grunn. Du finner at de fleste nettlesere fulgte IEs ledelse i å identifisere seg som Mozilla. Tenk på det som en kjedereaksjon.

Videre lesning

Jeg anbefaler på det sterkeste at du leser Nicholas Zakas '"History of the User-Agent String", hvis du ønsker å dykke dypere.

6. Omfanget inkonsekvenser

Vurder følgende kode:

 // Opprett en funksjon som vil kalle en funksjon med navnet lik parameteren fn. funksjon foo (fn) if (typeof fn === "funksjon") fn ();  // Opprett et objekt med en eiendom og en metode. var bar = barbar: "Hei, Verden!", metode: funksjon () alert (this.barbar); ; bar.method (); // Alerts Hei, verden! foo (bar.method); // Hvis vi kaller foo-funksjonen, legg til pass "bar.method" -metoden, varsler det på en eller annen måte "undefined." foo (funksjon () bar.metode ();); // varsler Hei, Verden, etter

Årsaken til at foo (bar.method) ikke gir det samme resultatet, er fordi metoden funksjonen vil bli kalt som en metode for vinduet objektet, snarere enn bar. For å fikse dette må vi ringe bar.method () fra den angitte anonyme funksjonen.

Takk så mye til Jeremy McPeak for å varsle meg om denne feilen.

7. Bruken av bitwise operatører

JavaScript deler mange likheter med Java - en av dem er settet med bitvis operatører.

  • & - og
  • | - eller
  • ^ - xor
  • ~ - ikke
  • >> - signert høyre skift
  • ??? - usignert høyre skift
  • << - venstre shift

Vurder det første elementet, &; det ville være mye mer effektivt å bruke && operatøren, da det er raskere. Dette skyldes at JavaScript ikke er det samme som Java, og har ikke heltall. Som en slik prosess er det nødvendig med en relativt lang prosess for å konvertere operand, gjøre noe med det, og konverter det deretter tilbake.

Det er derfor du kan komme unna med å bruke & for "og" og | for "eller" - selv om du skal bruke && og ||.

8. For mange falske / bunnverdier

Kanskje dette ikke er en spesifikk feil i JavaScript, men det gjør absolutt læringsprosessen, spesielt for nybegynnere, en tøff en. Verdier som null, false og undefined betyr nesten det samme, men det er forskjeller som kan være forvirrende å forstå.

Falske verdier

For å teste, åpne konsollen i Firefox, og finn den boolske av følgende elementer.

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

Vær oppmerksom på at eventuelle andre verdier vil bli tolket som truthy.

Mer enn en feil, er disse mange falske verdiene bare forvirrende!

9. Det kan ikke gjøre aritmetisk

Ok, ok, jeg er 99% plager med overskriften ovenfor. Men JavaScript har noen få mindre problemer når man arbeider med decimaler, for eksempel ting som pengetransaksjoner. Åpne for eksempel konsollen din og logg ".2 + .4". Vi forventer at den skal vise ".6", riktig? Vel det gjør det, og det gjør det ikke!

 console.log (.2 + .4); // 0,6000000000000001

Hvorfor det? På et høyt nivå skyldes det at JavaScript brukte IEEE-standarden for binær flytende punkt-aritmetikk. Jeg, sannsynligvis som deg, forstår ikke helt hva som spesifiseres, men vet bare at når du arbeider med desimaltall, kan resultatene variere litt fra det du forventer. Husk at heltall aritmetikk er perfekt, så dette er egentlig ikke et stort problem.

10. Kode Styling er ikke ditt valg!

Når det gjelder kodestilen din, er det akkurat det: din stil. Noen foretrekker å plassere sine krøllete braces på samme linje som kontrollen, andre foretrekker at det går på egenhånd.

 // braces til høyre retur foo: bar; // braces på egen linje retur foo: bar;

Avhengig av den første web dev-boken vi leser, eller hvordan læreren lærte oss, er det helt akseptabelt å bruke en av metodene ovenfor, eller til og med en kombinasjon av de to. Problemet med JavaScript er at det ikke er ditt valg!

Jeg lærte dette eksemplet fra et foredrag som Doug Crockford ga rundt for et år siden. Vurder tilbakemelding fra ovenfra. Tro det eller ei, de er ikke like. Tro ikke på meg? Prøv dette ut. Legg til følgende på enkelte HTML-sider.

 var foo = funksjon () retur a: 'b';  (); alert (foo.a); // b

Koden ovenfor oppretter bare en variabel som heter foo, som er lik den returnerte objekten. Når vi varsler (foo.a), ser vi, som forventet, en varselboks med en verdi av 'b'. Nå bare ta den åpningen krøllete brace, fra retur uttalelsen, og skyv den ned til sin egen linje, slik som.

 returnere a: 'b';

Hvis du kjører det i nettleseren din, får du en Firebug-feil, og logger på at "foo er udefinert." Hva i helvete!? :)

Så hvorfor gjør JavaScript dette? Det er på grunn av noe som heter "semicolon insertion." I hovedsak vil JavaScript forsøke å korrigere vår dårlige koding. Hvis du for eksempel mener at du har slått av en lukkende semikolon, vil den fortsette og legge den på for deg. Selv om dette var opprinnelig ment å være en bekvemmelighet, spesielt for nyere JavaScripters, er det faktisk en veldig dårlig ting når du ikke har kontroll over din egen kode, som vist ovenfor.

I vårt eksempel er det ingen måte å avgjøre hvorfor foo.a returnerer "undefined." Nå som vi er klar over semikoloninnsetting, er årsaken til at den ikke er definert fordi JavaScript vil legge til et semikolon til slutten av returerklæringen.

 komme tilbake; // JS legger feil i dette semikolonet. a: 'b'; // Det vil også legge til et semikolon, fordi det ikke skjønner at dette er et objekt. ;

Så, hvis vi umiddelbart kommer tilbake, har det ingen anelse om hva eiendommen "a" er, og dermed resulterer i "udefinert".

Konklusjon

Som jeg nevnte i begynnelsen av denne artikkelen, elsker jeg JavaScript og bruker det daglig. Men det betyr ikke at det ikke er noen veldig forferdelige feil på språket. Jeg vil gjerne høre dine tanker i kommentarene! Takk for at du leste. Retweets og Diggs blir alltid verdsatt! Takk så mye til Jeremy McPeak, Doug Crockford, Nicholas Zakas og John Resig: Jeg henviste til opplæringene og bøkene dine når du lagde denne artikkelen ut.

  • Følg oss på Twitter, eller abonner på Nettuts + RSS-feed for de beste webutviklingsopplæringene på nettet.