The document provides JavaScript best practices focusing on code quality, avoiding antipatterns like implied globals and eval, and recommendations for style like indentation and naming conventions. It also discusses testing with Jasmine including writing tests, making them pass, refactoring code, and repeating the test-driven development process. Modular code organization techniques like revealing module pattern and event publishing are also covered.
6. Implied globals
Forgetting var
vrfo=fnto( {
a o ucin)
br=1
a ;
};
7. Boolean type conversion
To Truthy or to Falsy. That is the only question!
vre =dcmn.eEeetyd'osnteit)
a l ouetgtlmnBI(de_o_xs';
i(l= fle {
fe = as)
aet"hud' w seti msae!)
lr(solnt e e hs esg?";
}
8. Trailing comma
works on my machine!
vrfo={
a o
br "a"
a: br,
bz "a"
a: bz,
};
9. Return undefined
señor developers wear mustaches
{
vrfo=fnto( {
a o ucin)
rtr
eun
{
x:"ok lk C nw"
los ie # o!
};
}
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. for .. in
use a framework
vrdt ={
a aa
fo "h,
o: o"
br "y
a: m"
}
fr(a di dt){
o vr n aa
cnoelgdt[];
osl.o(aad)
}
13. for .. in
& never touch Object.prototype
Ojc.rttp.eAohrotig=fnto( {
betpooyeytnteTSrn ucin)
rtr "o"
eun gd;
}
14. Hoisting
declare upfront all variables
vrfo="lbl;
a o goa"
vrbr=fnto( {
a a ucin)
aetfo;
lr(o)
vrfo="oa"
a o lcl;
aetfo;
lr(o)
};
15. Eval
... and the job is done
fnto poMnJoPre(et {
ucin orassnasrtx)
rtr ea(( +tx +"";
eun vl"" et ))
}
vrtx ='{"el":"ol"}'
a et hlo wrd ;
vrjo =poMnJoPre(et;
a sn orassnasrtx)
16. Eval is evil!
Never ever!
vrtx ='fnto( {aet"akd";}('
a et ucin) lr(hce!) ) ;
17. Globals
the mother of all antipatterns
fnto fo){
ucin o(
rtr "a"
eun br;
}
cnoelgti[fo]);
osl.o(hs'o'()
18. Every time you clutter the global namespace,
somewhere in the world a helpless kitten dies!
21. Globals
reduce, minimize, delete or kill them
(ucin){"t? }(;
fnto( wf" ))
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. Lookup tables
avoid the switch-case syndrome
vrmtos={
a ehd
1 dFrt
: ois,
2 dScn,
: oeod
3 dTid
: ohr
};
i (ehd[oehn] {
f mtossmtig)
mtossmtig(;
ehd[oehn])
}
24. Inheritance
favour composition over inheritance (FCoI)
“ Because inheritance exposes a subclass
to details of its parent's implementation,
it's often said that 'inheritance breaks
encapsulation'. ”
(Gang of Four 1995:19)
25. Revealing Module
Pattern
vrmRvaigoue=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
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 systems
integrates
31. Output
Jsie131rvso 15561
amn .. eiin 34593 fnse i 008
iihd n .1s
•••••
Psig5ses
asn pc N tycth
o r/ac
Pae
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. Hello World
vrhlool =fnto( {
a elWrd ucin)
rtr "el Wrd"
eun Hlo ol!;
};
dsrb(hlool' fnto( {
ecie'elWrd, ucin)
i(sy hlo,fnto( {
t'as el' ucin)
epc(elWrd).oqa(HloWrd";
xethlool()tEul"el ol!)
};
)
};
)
jsiegtn(.xct(;
amn.eEv)eeue)
hint: press F12 and paste this code!
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. 1. Write your test
dsrb(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. 2. Watch them fail
vrsvFra =fnto( {
a aeomt ucin)
rtr "o!;
eun bo"
};
jsiegtn(.xct(;
amn.eEv)eeue)
Demo
38. 3. Make them pass
vrsvFra =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. 4. Refactor
fnto 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. 5. Repeat
fnto 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. Testing HTML
Jasmine is DOM agnostic
comes 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. First Solution
in memory fixture with jQuery
dsrb(tiiljur pui' fnto ( {
ecie'rva 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 ( {
t'hud o oehn' ucin )
fxuemPui(;
itr.ylgn)
epc(itr)tHvCas"eCas)
xetfxue.oaels(nwls";
};
)
};
)
jsiegtn(.xct(;
amn.eEv)eeue)
... only works for trivial plugins!
43. Clumsy Solution
directly append to/remove from DOM
dsrb(m jur pui' fnto ( {
ecie'y Qey lgn, ucin )
bfrEc(ucin( {
eoeahfnto )
$'fxue)rmv(;
(#itr'.eoe)
$'oy)apn(<i i=fxue>TL/i>)
(bd'.ped'dv d"itr"HM<dv';
};
)
i(sol d smtig,fnto ( {
t'hud o oehn' ucin )
$'fxue)mPui(;
(#itr'.ylgn)
epc((#itr')tHvCas"eCas)
xet$'fxue).oaels(nwls";
};
)
};
)
jsiegtn(.xct(;
amn.eEv)eeue)
44. jasmine-jquery
custom matchers , HTML/style/JSON fixtures, event spies
dsrb(m jur pui' fnto ( {
ecie'y Qey lgn, ucin )
bfrEc(ucin){
eoeahfnto(
jsiegtitrs)fxuePt=j/_amn-eojur'
amn.eFxue(.itrsah's5jsiedm_qey;
jsiegtitrs)la(jur.ylgnse.tl)
amn.eFxue(.od'qeymPui.pchm';
};
)
i(sol d smtig,fnto( {
t'hud 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
46. Spies
test behaviour
dsrb(Gril' fnto ( {
ecie'afed, ucin )
dsrb(we tl t b nc' fnto( {
ecie'hn 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( {
t'hud nwr ih k, ucin)
vrase =gril.eie)
a nwr afedbNc(;
epc(nwr.oqa(o";
xetase)tEul"k)
};
)
i(sol selpza,fnto ( {
t'hud 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