mikkel lauritsen bloghoved den gode kode

Sprogdele retrofittes til JavaScript - med halvgodt resultat

Jeg har fået skrevet en masse JavaScript-kode her på det sidste, og det er egentlig ret imponerende, hvad man efterhånden har fået vredet ud af sproget. Som RFC 1925 (som egentlig handler om netværk men også passer fint her) siger: With sufficient thrust, pigs fly just fine.

Sproget har flere gode sider, bl.a.

  • JavaScript er tilgængeligt i alle browsere og dermed i alle klienter, fra billige smartphones til PC'er.
  • Transpilere og polyfills gør det muligt at bruge en rimeligt moderne udgave af sproget.
  • Debuggeren og de øvrige udviklingsværktøjer i Chrome (og sikkert også andre browsere) er (efter forholdene) meget velfungerende.

Der er så bare også flere... æh, mindre positive ting ved det.

Der er for mange ting, som er svært gennemskuelige. En ting er this, som bliver udsat for de vildeste former for sort magi, men selv en principielt set simpel ting som hvilke parametre der gives med ved funktionskald kan være kompleks. Fra Redux:

export default function createStore(reducer, initialState, enhancer) {
  if (typeof initialState === 'function' && typeof enhancer === 'undefined') {
    enhancer = initialState
    initialState = undefined
  }

Selv om mange fortalere for JavaScript har lovsunget sproget for dets dynamik, prototypebaserethed og andre særpræg har man åbenbart indset, at der er dele af andre sprog, som giver god menig. De er så blevet retrofittet på JS, men bare i dårligere udgaver. Eksempler:

  • Klasser. Der er ingen membervariable i ES6 og ES7 (WTF?), og hvad værre er løser de ikke problemet med at metoderne eksplicit skal bindes til this. Det er i øvrigt interessant, at der findes masser af eksempler på at man kan håndtere det ved at bruge fat arrow functions, men det kan man så alligevel ikke, når det handler om metoder - i hvert fald ikke med Babel.
  • Moduler. Alting håndteres på runtime, og der er ingen form for discoverability.
  • Typechecks. Vi bruger fx jsonschema til at validere, at applikationens tilstand ser ud som forventet, men det ville godt nok være meget nemmere, hvis man bare kunne bruge statisk typede data.

Det virker også som en meget gammeldags måde at udvikle på (selv om alle de nedenstående ankepunkter strengt taget ikke er knyttet til sproget selv):

  • Vi har udviklings- og produktionsbyg, hvilket jeg SVJH aldrig har brugt med Java.
  • Det er en langsom byggeproces. Med vores nuværende (langt fra komplette) applikation tager det 3-4 sekunder for webpack at bygge i udviklingsmode og 15 sekunder i produktionsmode - det er måske absolut set ikke lang tid, men når nu en af pointerne med sprogets dynamik er at muliggøre mere iterativ udvikling er det bare for langsomt. FWIW tager det 2 sekunder at compile Javadelen af applikationen og samle alle artifakterne i en warfil.
  • Refaktoreringer - og dem laver vi masser af - er i vidt omfang manuelle, fordi der er dårlig værktøjsunderstøttelse.
  • Jeg er begyndt også at debugge med console.log() rundt omkring i koden. De mange callbacks gør det svært at følge flowet rundt i koden, og når man rammer et breakpoint kan debuggeren ikke vise andet end en masse instanser af hvad der i Java er Map<String, Object>.
  • Tests skal bl.a. erstatte statiske checks på compiletime. De tager alt for lang tid at køre, og det giver meget mere vedligehold - man sidder også og refaktorerer tests, når man ændrer koden.

Det er nok for meget at håbe på, at de udbredte browsere skulle se lyset og stille en bedre runtimeplatform til rådighed, så er TypeScript vejen frem? Det kan hænge sammen med JSX, så det er en god start.

Kommentarer (5)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
#1 Torben Mogensen Blogger

TypeScript er Microsofts udvidelse af JavaScript med statiske typer, klassebaseret OO-programmering og et par andre forbedringer, men det oversætter til normal JavaScript, så man kan køre programmerne alle steder, hvor JavaScript kan køre.

De statiske typer er helt frivillige, så man kan uden videre bruge sine JavaScript programmer i TypeScript og tilføje typer efter behov/ønske.

Jeg siger ikke, at TypeScript er verdens bedste sprog, men det løser nogle af de problemer, der er med JavaScript.

  • 2
  • 0
#2 Baldur Norddahl

Prøv at tage et hurtigt kig på det her: http://www.lihaoyi.com/hands-on-scala-js/

Scala er et godt match til JavaScript da der er mange ligheder i sprogene. Man kan skrive små kodestumper der er valide i begge sprog.

Scala-JS oversætter Scala til JavaScript. Det er der også andre der kan (eksempelvis TypeScript). I forhold til TypeScript så kommer Scala-JS med et stærkere sprog (muligvis subjektiv holdning) og integration med Scala/Java på server siden.

I forhold til mange andre har Scala næsten perfekt integration med JavaScript. Det er således helt almindeligt at blande Scala-JS med gængse JavaScript frameworks.

En ulempe er dog at oversætteren ikke er specielt hurtig. Den er ikke ekstrem langsom, men hvis 4 sekunder allerede skræmmer, så skuffer Scala-JS oversætteren nok på dette punkt.

  • 0
  • 0
#3 Jacob Christian Munch-Andersen

Jeg har også skrevet en hel del JavaScript. Jeg har stadig til gode at finde et framework som løser flere problemer end det skaber.

  • Når først projektet er sovset ind i en cross-compiler har man et irriterende ekstra trin hver gang man tester, og det er best-case hvor build-processen virker som den skal.
  • Fejlmeddelelser, stack-traces osv. refererer ikke til kildekoden. Alt efter værktøj og situation er det faktiske resultat et sted mellem nogenlunde læseligt og totalt ubrugeligt.
  • Frameworks løser nogle få lette problemer, de svære problemer er i bedste fald ikke blevet sværere.

Til gengæld virker HTML og JavaScript uden for mange dikkedarer ganske fint. Der er nogle uheldige pletter (e.g. + operatoren), men det der typisk irriterer mig mest er performance, selv med V8 er det stadig et mellemlangsomt sprog, hvis altså vel at mærke optimizeren kan lide ens kode. Og der er nogle underlige funktionelle huller hvor det godt nok ikke er svært at skrive koden selv, men kropumuligt at få ordentlig performance ud af løsningen.

  • 2
  • 0
#5 Torben Mogensen Blogger

Jeg giver ham ret så langt som, at JavaScripts implicitte konverteringer er noget skidt, og at det betyder, at det er svært at svejse et statisk typesystem ovenpå, når typen af input fra f.eks. en browser ikke typevalideres.

Men han burde fra starten have skrevet sin app, så den forventede strings fra browseren og eksplicit konvertere disse til tal -- ikke bare ved at sætte et + foran, men ved at verificere, at alle tegnene er cifre (evt. med foranstillet fortegn). Ja, det er bøvlet at skulle det, men hvis sproget ikke laver inputvalidering, så må man selv træde til.

  • 1
  • 0
Log ind eller Opret konto for at kommentere