JS Best PracticesCreated by Johannes Hoppe
My GoalHigher code qualitiy. Pragmatic solutions.             No fancy stuff.
Know Your MS Tools
Visual Studio 2010/2012JScript Editor ExtensionsResharper 7.1JSHintChutzpahFirebug / F12
Know the pitfalls
Implied globals               Forgetting varvrfo=fnto( { a o   ucin)   br=1   a   ;};
Boolean type conversion         To Truthy or to Falsy. That is the only question!vre =dcmn.eEeetydosnteit)a l   ouetgtlmnB...
Trailing comma            works on my machine!vrfo={ a o   br "a"   a: br,   bz "a"   a: bz,};
Return undefined             señor developers wear mustaches                       {vrfo=fnto( { a o    ucin)   rtr    eun...
Associative arrays             they dont existvrx=[;a    ]xo ="a"[fo]   br;
try .. catch .. finally                 who cares about the reason?vrfo=fnto( { a o     ucin)   ty{    r      dCaytf;     ...
for .. in                 use a frameworkvrdt ={ a aa   fo "h,   o: o"   br "y   a: m"}fr(a di dt){ o vr  n aa   cnoelgdt[...
for .. in           & never touch Object.prototype Ojc.rttp.eAohrotig=fnto( {  betpooyeytnteTSrn  ucin)   rtr "o"   eun gd;}
Hoisting                declare upfront all variablesvrfo="lbl; a o goa"vrbr=fnto( { a a   ucin)   aetfo;   lr(o)   vrfo="...
Eval               ... and the job is donefnto poMnJoPre(et { ucin orassnasrtx)   rtr ea(( +tx +"";   eun vl""  et   ))}vr...
Eval is evil!                Never ever!vrtx =fnto( {aet"akd";}(a et   ucin)   lr(hce!) ) ;
Globals             the mother of all antipatternsfnto fo){ ucin o(   rtr "a"   eun br;}cnoelgti[fo]);osl.o(hso()
Every time you clutter the global namespace,somewhere in the world a helpless kitten dies!
Pretty Code
Coding conventions 1.   intentation (4 spaces!) 2.   curly braces everywhere 3.   semicolons everywhere 4.   constructor f...
Globals          reduce, minimize, delete or kill them(ucin){"t? }(;fnto(   wf" ))
The switch-case         syndrome               a functional language wants functions!sic (oehn){wth smtig    cs 1    ae : ...
Lookup tables            avoid the switch-case syndromevrmtos={ a ehd   1 dFrt    : ois,   2 dScn,    : oeod   3 dTid    :...
Inheritance       favour composition over inheritance (FCoI)“ Because inheritance exposes a subclassto details of its pare...
Revealing Module            PatternvrmRvaigoue=fnto ( {a yeelnMdl   ucin )    vr_ae="oans;    a nm  Jhne"    fnto getns){ ...
Modul loaders                 use AMD (require.js)dfn(ts [jur,fnto( {eieet, qey] ucin)     rtr {      eun        syoehn :f...
Events              Publish/Subscribe Patternvr$vns=${)a eet   (};$vnsbn(smtigapn fnto( {eet.idoehnHpes, ucin)   aet"oehn ...
TDD with Jasmine
Why Jasmine?              similar to JSpec or RSpec, BDD-style    created by authors of jsUnit and Screw.Unit             ...
Jasmine Bootstrap<DCYEhm>!OTP tl<tlhm><edha>  <il>amn Se Rne<tte   tteJsie pc unr/il>  <ikrl"tlset he=lbjsie131jsiecs /   ...
OutputJsie131rvso 15561 amn .. eiin 34593                     fnse i 008                                        iihd n .1s...
Hello Worldvrhlool =fnto( { a elWrd   ucin)   rtr "el Wrd"   eun Hlo ol!;};dsrb(hlool fnto( {ecieelWrd, ucin)  i(sy hlo,fn...
Matchersepc()tEuly;xetx.oqa()epc()tB()xetx.oey;epc()tMthpten;xetx.oac(atr)epc()tBDfnd)xetx.oeeie(;epc()tBUdfnd)xetx.oeneie...
Own matchersbfrEc(ucin( {eoeahfnto )   ti.dMthr(   hsadaces{      iAa:fnto ( {       sCt ucin )        rtr ti.culiFuf( & t...
Test-Driven Development                                     1.   Write your tests                                     2.  ...
1. Write your testdsrb(svFra" fnto ( {ecie"aeomt, ucin )     vroiia =0 -{}-{};     a rgnl   {}  1 2     i(sol rpaepaeodr" ...
2. Watch them failvrsvFra =fnto( { a aeomt   ucin)   rtr "o!;   eun bo"};jsiegtn(.xct(; amn.eEv)eeue)Demo
3. Make them passvrsvFra =fnto(x){a aeomt   ucintt   $agmns.ahfnto (,ie){   (ruet)ec(ucin i tm      i ( >0 {       f i   )...
4. Refactorfnto hmEcd(nu){ ucin tlnoeipt   rtr ((<i/.etipt.tl);   eun $dv>)tx(nu)hm()}vrsvFra =fnto(x){a aeomt   ucintt   ...
5. Repeatfnto hmEcd(nu){ ucin tlnoeipt   rtr ((<i/.etipt.tl);   eun $dv>)tx(nu)hm()}vrsvFra =fnto( {a aeomt   ucin)   vrag...
Testing HTML        Jasmine is DOM agnosticcomes without tools to set up HTML fixtures                                    ...
First Solution            in memory fixture with jQuerydsrb(tiiljur pui fnto ( {ecierva Qey lgn, ucin )  vrfxue  a itr;  b...
Clumsy Solution           directly append to/remove from DOMdsrb(m jur pui fnto ( {eciey Qey lgn, ucin )  bfrEc(ucin( {  e...
jasmine-jquery         custom matchers , HTML/style/JSON fixtures, event spiesdsrb(m jur pui fnto ( {eciey Qey lgn, ucin )...
TDD → BDD
Spies                           test behaviourdsrb(Gril fnto ( {ecieafed, ucin )  dsrb(we tl t b nc fnto( {   eciehn od o ...
Danke!
Upcoming SlideShare
Loading in …5
×

2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices

1,134 views

Published on

Of course, a presentation about JavaScript should be made with HTML5 & JavaScript. So, here it is! Enjoy the show at http://johanneshoppe.github.com/JsBestPractices/ . You might also want to fork it on GitHub (https://github.com/JohannesHoppe/JsBestPractices) or save it as an old-fashioned static PDF from Slideshare.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,134
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
19
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

2013-02-21 - .NET UG Rhein-Neckar: JavaScript Best Practices

  1. 1. JS Best PracticesCreated by Johannes Hoppe
  2. 2. My GoalHigher code qualitiy. Pragmatic solutions. No fancy stuff.
  3. 3. Know Your MS Tools
  4. 4. Visual Studio 2010/2012JScript Editor ExtensionsResharper 7.1JSHintChutzpahFirebug / F12
  5. 5. Know the pitfalls
  6. 6. Implied globals Forgetting varvrfo=fnto( { a o ucin) br=1 a ;};
  7. 7. Boolean type conversion To Truthy or to Falsy. That is the only question!vre =dcmn.eEeetydosnteit)a l ouetgtlmnBI(de_o_xs;i(l= fle { fe = as) aet"hud w seti msae!) lr(solnt e e hs esg?";}
  8. 8. Trailing comma works on my machine!vrfo={ a o br "a" a: br, bz "a" a: bz,};
  9. 9. Return undefined señor developers wear mustaches {vrfo=fnto( { a o ucin) rtr eun { x:"ok lk C nw" los ie # o! };}
  10. 10. Associative arrays they dont existvrx=[;a ]xo ="a"[fo] br;
  11. 11. try .. catch .. finally who cares about the reason?vrfo=fnto( { a o ucin) ty{ r dCaytf; orzSuf }cth(){ ac e rtr fle eun as; } rtr tu; eun re};
  12. 12. for .. in use a frameworkvrdt ={ a aa fo "h, o: o" br "y a: m"}fr(a di dt){ o vr n aa cnoelgdt[]; osl.o(aad)}
  13. 13. for .. in & never touch Object.prototype Ojc.rttp.eAohrotig=fnto( { betpooyeytnteTSrn ucin) rtr "o" eun gd;}
  14. 14. Hoisting declare upfront all variablesvrfo="lbl; a o goa"vrbr=fnto( { a a ucin) aetfo; lr(o) vrfo="oa" a o lcl; aetfo; lr(o)};
  15. 15. Eval ... and the job is donefnto poMnJoPre(et { ucin orassnasrtx) rtr ea(( +tx +""; eun vl"" et ))}vrtx ={"el":"ol"}a et hlo wrd ;vrjo =poMnJoPre(et;a sn orassnasrtx)
  16. 16. Eval is evil! Never ever!vrtx =fnto( {aet"akd";}(a et ucin) lr(hce!) ) ;
  17. 17. Globals the mother of all antipatternsfnto fo){ ucin o( rtr "a" eun br;}cnoelgti[fo]);osl.o(hso()
  18. 18. Every time you clutter the global namespace,somewhere in the world a helpless kitten dies!
  19. 19. Pretty Code
  20. 20. Coding conventions 1. intentation (4 spaces!) 2. curly braces everywhere 3. semicolons everywhere 4. constructor functions: UpperCamelCase 5. all other: lowerCamelCase
  21. 21. Globals reduce, minimize, delete or kill them(ucin){"t? }(;fnto( wf" ))
  22. 22. The switch-case syndrome a functional language wants functions!sic (oehn){wth smtig cs 1 ae : dFrt) ois(; bek ra; cs 2 ae : dScn(; oeod) bek ra; cs 3 ae : dTid) ohr(; bek ra;}
  23. 23. Lookup tables avoid the switch-case syndromevrmtos={ a ehd 1 dFrt : ois, 2 dScn, : oeod 3 dTid : ohr};i (ehd[oehn] { f mtossmtig) mtossmtig(; ehd[oehn])}
  24. 24. Inheritance favour composition over inheritance (FCoI)“ Because inheritance exposes a subclassto details of its parents implementation, its often said that inheritance breaks encapsulation. ” (Gang of Four 1995:19)
  25. 25. Revealing Module PatternvrmRvaigoue=fnto ( {a yeelnMdl ucin ) vr_ae="oans; a nm Jhne" fnto getns){ ucin reig( cnoelg"el "+_ae; osl.o(Hlo nm) } fnto staenm){ ucin eNm(ae _ae=nm; nm ae } rtr { eun stae stae eNm: eNm, getns getns reig: reig };})(;» Documentation
  26. 26. Modul loaders use AMD (require.js)dfn(ts [jur,fnto( {eieet, qey] ucin) rtr { eun syoehn :fnto( {aet"el!) } aSmtig ucin) lr(hlo"; }};)rqie[ts,fnto(){eur(et] ucint tsyoehn(; .aSmtig)};)
  27. 27. Events Publish/Subscribe Patternvr$vns=${)a eet (};$vnsbn(smtigapn fnto( {eet.idoehnHpes, ucin) aet"oehn hpee!) lr(Smtig apnd";};)$vnstigroehnHpes)eet.rge(smtigapn;
  28. 28. TDD with Jasmine
  29. 29. Why Jasmine? similar to JSpec or RSpec, BDD-style created by authors of jsUnit and Screw.Unit from any browser, DOM,independent framework or host language into continuous build systemsintegrates
  30. 30. Jasmine Bootstrap<DCYEhm>!OTP tl<tlhm><edha> <il>amn Se Rne<tte tteJsie pc unr/il> <ikrl"tlset he=lbjsie131jsiecs / ln e=syehe" rf"i/amn-../amn.s" > <citsc"i/amn-../amn.s>/cit srp r=lbjsie131jsiej"<srp> <citsc"i/amn-../amn-tlj"<srp> srp r=lbjsie131jsiehm.s>/cit <- icuesuc flshr..-> !- nld ore ie ee. - <citsc"r/lyrj"<srp> srp r=scPae.s>/cit <citsc"r/ogj"<srp> srp r=scSn.s>/cit <- icuese flshr..-> !- nld pc ie ee. - <citsc"pcSeHle.s>/cit srp r=se/pceprj"<srp> <citsc"pcPaeSe.s>/cit srp r=se/lyrpcj"<srp> <cit srp> (ucin( { fnto ) vrhmRpre =nwjsieHmRpre(; a tleotr e amn.tleotr) vrjsien =jsiegtn(; a amnEv amn.eEv) jsien.dRpre(tleotr; amnEvadeotrhmRpre) jsien.pcitr=fnto (pc { amnEvseFle ucin se) rtr hmRpre.pcitrse) eun tleotrseFle(pc; }; vrcretidwnod=wno.nod a urnWnoOla idwola; wno.nod=fnto ( { idwola ucin )
  31. 31. OutputJsie131rvso 15561 amn .. eiin 34593 fnse i 008 iihd n .1s•••••Psig5ses asn pc N tycth o r/acPae lyr sol b al t pa aSn hud e be o ly og we sn hsbe pue hn og a en asd sol idct ta tesn i cretypue hud niae ht h og s urnl asd sol b psil t rsm hud e osbe o eue tlstecretsn i teue hsmd i afvrt el h urn og f h sr a ae t aoie #eue rsm sol trwa ecpini sn i araypaig hud ho n xeto f og s led lyn
  32. 32. Hello Worldvrhlool =fnto( { a elWrd ucin) rtr "el Wrd" eun Hlo ol!;};dsrb(hlool fnto( {ecieelWrd, ucin) i(sy hlo,fnto( { tas el ucin) epc(elWrd).oqa(HloWrd"; xethlool()tEul"el ol!) }; )};)jsiegtn(.xct(;amn.eEv)eeue) hint: press F12 and paste this code!
  33. 33. Matchersepc()tEuly;xetx.oqa()epc()tB()xetx.oey;epc()tMthpten;xetx.oac(atr)epc()tBDfnd)xetx.oeeie(;epc()tBUdfnd)xetx.oeneie(;epc()tBNl(;xetx.oeul)epc()tBTuh(;xetx.oerty)epc()tBFly)xetx.oeas(;epc()tCnany;xetx.ooti()epc()tBLsTa()xetx.oeeshny;epc()tBGetrhny;xetx.oeraeTa()epc(ucin)f(;)tTrwe;xetfnto({n)}.oho()
  34. 34. Own matchersbfrEc(ucin( {eoeahfnto ) ti.dMthr( hsadaces{ iAa:fnto ( { sCt ucin ) rtr ti.culiFuf( & ti.culiLz(; eun hsata.slfy) & hsata.say) } }; )};)dsrb(Gril fnto ( {ecieafed, ucin ) i(i act,fnto ( { ts a ucin ) epc(e Gril()iAa(; xetnw afed).sCt) }; )};)» Documentation
  35. 35. Test-Driven Development 1. Write your tests 2. Watch them fail 3. Make them pass 4. Refactor 5. Repeat see Growing Object-Oriented Software, Guidedorby Tests , page 6 see Working Effectively with Legacy Code , page 62 many other
  36. 36. 1. Write your testdsrb(svFra" fnto ( {ecie"aeomt, ucin ) vroiia =0 -{}-{}; a rgnl {} 1 2 i(sol rpaepaeodr" fnto ( { t"hud elc lchles, ucin ) vrepce = -B-C; a xetd A vrfrae =svFra(rgnl ; a omtd aeomtoiia, A, B, C) epc(omtd.oqa(xetd; xetfrae)tEulepce) }; ) i(sol ecd ijce cnet,fnto ( { t"hud noe netd otn" ucin ) vrepce = -&tbg;ETl;bg;-C; a xetd A l;&tTS&t/&t vrfrae =svFra(rgnl bTS<b ; a omtd aeomtoiia, A, <>ET/>, C) epc(omtd.oqa(xetd; xetfrae)tEulepce) }; )};)
  37. 37. 2. Watch them failvrsvFra =fnto( { a aeomt ucin) rtr "o!; eun bo"};jsiegtn(.xct(; amn.eEv)eeue)Demo
  38. 38. 3. Make them passvrsvFra =fnto(x){a aeomt ucintt $agmns.ahfnto (,ie){ (ruet)ec(ucin i tm i ( >0 { f i ) ie =((<i/.etie)hm() tm $dv>)tx(tm.tl); tt=ttrpae""+( -1 +"" ie) x x.elc({ i ) }, tm; } }; ) rtr tt eun x;};jsiegtn(.xct(; amn.eEv)eeue)Demo
  39. 39. 4. Refactorfnto hmEcd(nu){ ucin tlnoeipt rtr ((<i/.etipt.tl); eun $dv>)tx(nu)hm()}vrsvFra =fnto(x){a aeomt ucintt $ec(ruet,fnto (,ie){ .ahagmns ucin i tm i ( >0 { f i ) ie =hmEcd(tm; tm tlnoeie) tt=ttrpae""+( -1 +"" ie) x x.elc({ i ) }, tm; } }; ) rtr tt eun x;};jsiegtn(.xct(; amn.eEv)eeue)Demo
  40. 40. 5. Repeatfnto hmEcd(nu){ ucin tlnoeipt rtr ((<i/.etipt.tl); eun $dv>)tx(nu)hm()}vrsvFra =fnto( {a aeomt ucin) vrag =Arypooyesiecl(ruet) a rs ra.rttp.lc.alagmns; vrtt=ag.hf(; a x rssit) $ec(rs fnto (,ie){ .ahag, ucin i tm ie =hmEcd(tm; tm tlnoeie) tt=ttrpae""+i+"" ie) x x.elc({ }, tm; }; ) rtr tt eun x;};jsiegtn(.xct(; amn.eEv)eeue)Demo
  41. 41. Testing HTML Jasmine is DOM agnosticcomes without tools to set up HTML fixtures Definition: A test fixture is a fixed state of a set of objects used as a baseline for running tests.
  42. 42. First Solution in memory fixture with jQuerydsrb(tiiljur pui fnto ( {ecierva Qey lgn, ucin ) vrfxue a itr; bfrEc(ucin( { eoeahfnto ) fxue=$dvsm HM cd hr<dv; itr (<i>oe TL oe ee/i>) }; ) i(sol d smtig,fnto ( { thud o oehn ucin ) fxuemPui(; itr.ylgn) epc(itr)tHvCas"eCas) xetfxue.oaels(nwls"; }; )};)jsiegtn(.xct(;amn.eEv)eeue) ... only works for trivial plugins!
  43. 43. Clumsy Solution directly append to/remove from DOMdsrb(m jur pui fnto ( {eciey Qey lgn, ucin ) bfrEc(ucin( { eoeahfnto ) $fxue)rmv(; (#itr.eoe) $oy)apn(<i i=fxue>TL/i>) (bd.peddv d"itr"HM<dv; }; ) i(sol d smtig,fnto ( { thud o oehn ucin ) $fxue)mPui(; (#itr.ylgn) epc((#itr)tHvCas"eCas) xet$fxue).oaels(nwls"; }; )};)jsiegtn(.xct(;amn.eEv)eeue)
  44. 44. jasmine-jquery custom matchers , HTML/style/JSON fixtures, event spiesdsrb(m jur pui fnto ( {eciey Qey lgn, ucin ) bfrEc(ucin){ eoeahfnto( jsiegtitrs)fxuePt=j/_amn-eojur amn.eFxue(.itrsahs5jsiedm_qey; jsiegtitrs)la(jur.ylgnse.tl) amn.eFxue(.odqeymPui.pchm; }; ) i(sol d smtig,fnto( { thud o oehn ucin) vr$i =$hlool.ylgn) a dv (#elWrd)mPui(; epc(dv.oaels(nwls"; xet$i)tHvCas"eCas) }; )};)jsiegtn(.xct(;amn.eEv)eeue)Demo
  45. 45. TDD → BDD
  46. 46. Spies test behaviourdsrb(Gril fnto ( {ecieafed, ucin ) dsrb(we tl t b nc fnto( { eciehn od o e ie, ucin) vrgril; a afed bfrEc(ucin){ eoeahfnto( gril =nwGril(; afed e afed) syngril,oordenEtiz.nClTruh) pO(afed gTFigAdaPza)adalhog(; }; ) i(sol ase wt o fnto( { thud nwr ih k, ucin) vrase =gril.eie) a nwr afedbNc(; epc(nwr.oqa(o"; xetase)tEul"k) }; ) i(sol selpza,fnto ( { thud ta iz ucin ) gril.eie) afedbNc(; epc(afedgTFigAdaPza.oaeenald) xetgril.oordenEtiz)tHvBeCle(; }; ) }; )};)jsiegtn(.xct(;amn.eEv)eeue) A spy can stub any function and tracks calls to it and all arguments.Demo
  47. 47. Danke!

×