Javascript patterns

  • 528 views
Uploaded on

The presentation covers Javascript Gotcha's and patterns to use while implementing client side browser applications.

The presentation covers Javascript Gotcha's and patterns to use while implementing client side browser applications.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
528
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
18
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. JavaScript  -­‐  What’s  in  the  language?  
  • 2. JavaScript  as  a  language  •  Implementa3on  of  ECMASCRIPT  •  Object  oriented  •  No  Classes  •  Dynamic  Objects  -­‐  collec3on  of  named  proper3es.  You  can  add,  remove,  update  its  members.    •  Loose  typing  •  lambdas  •  Na3ve  and  host  objects  -­‐  Environment  specific  •  Prototypical  inheritance  
  • 3. Good  Parts  •  Lambda  •  Dynamic  objects  •  Loose  typing  •  Object  literals  
  • 4. Bad  Parts  •  Global  Variables  •  +  adds  and  concatenates  •  Semicolon  inser3on  •  typeof  •  with  and  eval  •  ==  and  !=  •  false,  null,  undefined,  NaN  
  • 5. General  Pa8erns  
  • 6. Minimizing  global  variables  /*#Title:#Minimizing#Globals#Description:#they#are#declared#outside#of#function#or#simply#used#without#being#declared!*/!myglobal!=!"hello";!//#antipattern!console.log(myglobal);!//#"hello"!console.log(window.myglobal);!//#"hello"!console.log(window["myglobal"]);!//#"hello"!console.log(this.myglobal);!//#"hello"!
  • 7. Implied  global  variables  ! //!antipatten!1!! function!sum(x,!y)!{!! ! //!implied!global!! ! result!=!x!+!y;!! ! return!result;!! }!! //!preferred!1!! function!sum(x,!y)!{!//!a!variable!declared!inside!of!a!function!is!local!to!that!function!and!not!available!outside!the!function!! ! var!result!=!x!+!y;!! ! return!result;!! }!
  • 8. ! //"antipattern"2!! function!foo()!{!! ! var!a!=!b!=!0;!! ! //"...!! }!! //"the"preceding"code"snippet"will"behave"as"if"youve"typed"the"following!! var!a!=!(b!=!0);!! //"preferred"2!! function!foo()!{!! ! var!a,!b;!! ! //"...!! ! a!=!b!=!0;!//"both"local!! }!
  • 9. Single  var  PaSern  !! /*!Benefits:!!*!1.!Provides!a!single!place!to!look!for!all!the!local!variables!needed!by!the!function!! !*!2.!Prevents!logical!errors!when!a!variable!is!used!before!its!defined!! !*!3.!Helps!you!remember!to!declare!variables!and!therefore!minimize!globals!! */!! function!func()!{!! ! var!a!=!1,!! ! ! ! b!=!2,!! ! ! ! sum!=!a!+!b,!! ! ! ! myobject!=!{},!! ! ! ! i,!! ! ! ! j;!! ! //!function!body...!! }!! function!updateElement()!{!! ! var!el!=!document.getElementById("result"),!! ! ! ! style!=!el.style;!! ! //!do!something!with!el!and!style...!! }!
  • 10. Namespacing  ! //!unsafe!! var!MYAPP!=!{};!! //!better!! if!(typeof!MYAPP!===!"undefined")!{!! ! var!MYAPP!=!{};!! }!! //!or!shorter!! var!MYAPP!=!MYAPP!||!{};!
  • 11. ! MYAPP.namespace!=!function!(ns_string)!{!! ! var!parts!=!ns_string.split(.),!! ! ! ! parent!=!MYAPP,!! ! ! ! i;!! ! //"strip"redundant"leading"global!! ! if!(parts[0]!===!"MYAPP")!{!! ! ! parts!=!parts.slice(1);!! ! }!! ! for!(i!=!0;!i!<!parts.length;!i!+=!1)!{!! ! ! //"create"a"property"if"it"doesnt"exist!! ! ! if!(typeof!parent[parts[i]]!===!"undefined")!{!! ! ! ! parent[parts[i]]!=!{};!! ! ! }!! ! ! parent!=!parent[parts[i]];!! ! }!! ! return!parent;!! };!! //"assign"returned"value"to"a"local"var!! var!module2!=!MYAPP.namespace(MYAPP.modules.module2);!! console.log(module2!===!MYAPP.modules.module2);!//"true!
  • 12. Implied  Typecas3ng:  false,  null,  undefined,  NaN  ! var!zero!=!0;!! /*#antipattern!# #*#JavaScript#implicitly#typecasts#variables#when#you#compare#them.!# #*#Thats#why#comparisons#such#as#false#==#0#or#""#==#0#return#true.!# #*/!! if!(zero!==!false)!{!! ! //#this#block#is#executed...!! }!! //#preferred!! /*#To#avoid#confusion#caused#by#the#implied#typecasting,!*#always#use#the#===#and#!==#operators#that#check#both#the#values#and#the#type#of#the#expressions#you#compare!# */!! if!(zero!===!false)!{!! ! //#not#executing#because#zero#is#0,#not#false!! }!
  • 13. Avoiding  eval  /*!Title:!Avoiding!eval()!!*!Description:!avoid!using!eval()!!*/!//!antipattern!1!var!property!=!"name";!alert(eval("obj."!+!property));!//!preferred!1!var!property!=!"name";!alert(obj[property]);!
  • 14. /*#antipattern#2!*#Its#also#important#to#remember#that#passing#strings#to#setInterval(),#setTimeout(),!*#and#the#Function()#constructor#is,#for#the#most#part,#similar#to#using#eval()#and#therefore#should#be#avoided.!*/!setTimeout("myFunc()",!1000);!setTimeout("myFunc(1,!2,!3)",!1000);!//#preferred#2!setTimeout(myFunc,!1000);!setTimeout(function!()!{!! myFunc(1,!2,!3);!},!1000);!//#in#supported#browsers#(i.e.#not#IE)!setTimeout(myFunc,!1000,!1,!2,!3);!
  • 15. For-­‐in  loops  ! /*#Title:#for-in#loops!# #*#Description:#optimized#for-in#loops!# #*/!! //#the#object!! var!man!=!{!! ! hands:2,!! ! legs:2,!! ! heads:1!! };!! //#somewhere#else#in#the#code!! //#a#method#was#added#to#all#objects!! if!(typeof!Object.prototype.clone!===!undefined)!{!! ! Object.prototype.clone!=!function!()!{!! ! };!! }!
  • 16. ! //"antipattern!! //"for,in"loop"without"checking"hasOwnProperty()!! for!(var!i!in!man)!{!! ! console.log(i,!":",!man[i]);!! }!! /*!" "*"result"in"the"console!" "*"hands":"2!" "*"legs":"2!" "*"hands":"1!" "*"clone:"function()!" "*/!! //"preferred"1!! for!(var!i!in!man)!{!! ! if!(man.hasOwnProperty(i))!{!//"filter!! ! ! console.log(i,!":",!man[i]);!! ! }!! }!! /*!" "*"result"in"the"console!" "*"hands":"2!" "*"legs":"2!" "*"heads":"1!" "*/!
  • 17. Automa3c  semicolon  inser3on  //antipattern!return!{!!!!!status:!true!};!!//preferred!return{!!!!!status:!true!};!!
  • 18. Func:on  Pa8erns  
  • 19. Closures  //"Your"setup"function"can"store"some"private"data"in"a"closure"and"use"that"data"somehow.!//"Here"setup()"creates"a"counter"function,"which"gives"a"next"ID"for"example."But"the"count"variable"is"not"exposed.!var!setup!=!function!()!{!! var!count!=!0;!! return!function!()!{!! ! return!++count;!! };!};!//"usage!var!next!=!setup();!//next();"//"returns"1!//next();"//"returns"2!//next();"//"returns"3!
  • 20. Currying  /***!#currying!#***/!//#a#curried#add()!//#accepts#partial#list#of#arguments!function!add(x,!y)!{!! var!oldx!=!x,!oldy!=!y;!! if!(typeof!oldy!===!"undefined")!{!//#partial!! ! return!function!(newy)!{!! ! ! return!oldx!+!newy;!! ! }!! }!! //#full#application!! return!x!+!y;!}!//#test!typeof!add(5);!//#"function"!add(3)(4);!//#7!
  • 21. Literals,  Constructors  and  Object  crea:on  Pa8erns  
  • 22. To  ‘new’  or  not  ! ! !! //!antipattern!! var!car!=!new!Object();!! car.goes!=!"far";!! //!preferred!! var!car!=!{goes:"far"};!! //!constructor!! function!Waffle()!{!! ! this.tastes!=!"yummy";!! }!! //!antipattern!! //!forgotten!`new`!! var!good_morning!=!Waffle();!! console.log(typeof!good_morning);!//!"undefined"!! console.log(window.tastes);!//!"yummy"!! //!preferred!! var!good_morning!=!new!Waffle();!! console.log(typeof!good_morning);!//!"object"!! console.log(good_morning.tastes);!//!"yummy"!
  • 23. PaSerns  for  enforcing  ‘new’  !function!Waffle()!{!! if!(!(this!instanceof!Waffle))!{!! ! return!new!Waffle();!! }!! this.tastes!=!"yummy";!}!var!good_morning!=!new!Waffle();!var!good_evening!=!Waffle();!console.log(typeof!good_morning);!//""object"!console.log(good_morning.tastes);!//""yummy"!console.log(typeof!good_evening);!//""object"!console.log(good_evening.tastes);!//""yummy"!
  • 24. ! //!antipattern!! //!with!wrappers!! var!s!=!new!String("my!string");!! var!n!=!new!Number(101);!! var!b!=!new!Boolean(true);!! //!preferred!! //!without!wrappers!! var!s!=!"my!string";!! var!n!=!101;!! var!b!=!true;!
  • 25. /*!#only#use#primitive#wrappers#when#you#want#to#augment#the#value#and#persist#state!#*/!//#primitive#string!var!greet!=!"Hello!there";!//#primitive#is#converted#to#an#object!//#in#order#to#use#the#split()#method!greet.split(!)[0];!//#"Hello"!//#attemting#to#augment#a#primitive#is#not#an#error!greet.smile!=!true;!//#but#it#doesnt#actually#work!console.log(typeof!greet.smile);!//#"undefined"!//#primitive#wrapper!var!greet!=!new!String("Hello!there");!//#split()#method#is#called#directly#on#the#object!greet.split(!)[0];!//#"Hello"!//#augment#the#object!greet.smile!=!true;!console.log(typeof!greet.smile);!//#"boolean"!
  • 26. Module  paSern  MYAPP.utilities.array/=/(function/()/{// / / / //"private"properties// / / / var/array_string/=/"[object/Array]",// / / / ops/=/Object.prototype.toString,/// / / / //"private"methods// / / / inArray/=/function/(haystack,/needle)/{// / / / / for/(var/i/=/0,/max/=/haystack.length;/i/</max;/i/+=/1)// / / / / / if/(haystack[i]/===/needle)/{// / / / / / / return/i;// / / / / / }// / / / / }// / / / / return//1;// / / / },// / / / isArray/=/function/(a)/{// / / / / return/ops.call(a)/===/array_string;// / / / };// / / / //"end"var/// / / / //"revealing"public"API// / / / return/{// / / / / isArray:isArray,// / / / / indexOf:inArray// / / / };// / / }());/!
  • 27. Code  Reuse  Pa8erns  
  • 28. Prototypal  Inheritance  ! function!object(o)!{!! ! function!F()!{!! ! }!! ! F.prototype!=!o;!! ! return!new!F();!! }!! //"object"to"inherit"from!! var!parent!=!{!! ! name:"Papa"!! };!! //"the"new"object!! var!child!=!object(parent);!! //"testing!! console.log(child.name);!//""Papa"!
  • 29. //"parent"constructor!function!Person()!{!! //"an""own""property!! this.name!=!"Adam";!}!//"a"property"added"to"the"prototype!Person.prototype.getName!=!function!()!{!! return!this.name;!};!//"create"a"new"person!var!papa!=!new!Person();!//"inherit!var!kid!=!object(papa);!//"test"that"both"the"own"property!//"and"the"prototype"property"were"inherited!console.log(kid.getName());!//""Adam"!
  • 30. Augmen3ng  built-­‐in  Prototypes  if!(typeof!Object.prototype.myMethod!!==!"function")!{!! Object.prototype.myMethod!=!function!()!{!! ! //"implementation...!! };!}!
  • 31. Design  Pa8erns  
  • 32. CREATIONAL  Builder   constructs  complex  objects  by  separa3ng  construc3on  and  representa3on  Factory  Method   creates  objects  without  specifying  the  exact  class  to  create  Singleton   restricts  object  crea3on  for  a  class  to  only  one  instance  STRUCTURAL  Decorator   dynamically  adds/overrides  behavior  in  an  exis3ng  method  of  an  object  Facade   provides  a  simplified  interface  to  a  large  body  of  code  BEHAVIORAL  Chain  of  responsibility   delegates  commands  to  a  chain  of  processing  objects  Command   creates  objects  which  encapsulate  ac3ons  and  parameters  Mediator   allows  loose  coupling  between  classes  by  being  the  only  class  that  has  detailed  knowledge  of  their  methods  Observer   is  a  publish/subscribe  paSern  which  allows  a  number  of  observer  objects  to  see  an  event  
  • 33. Composite  //"Single"elements!$("#singleItem").addClass("active");!$("#container").addClass("active");!!//"Collections"of"elements!$("div").addClass("active");!$(".item").addClass("active");!$("input").addClass("active");!!
  • 34. Adapter  //"Cross"browser"opacity:!//"opacity:"0.9;""Chrome"4+,"FF2+,"Saf3.1+,"Opera"9+,"IE9,"iOS"3.2+,"Android"2.1+!//"filter:"alpha(opacity=90);""IE6KIE8!!//"Setting"opacity!$(".container").css({!opacity:.5!});!!//"Getting"opacity!var!currentOpacity!=!$(".container").css(opacity);!!
  • 35. Observer  //"Equivalent"to"subscribe(topicName,"callback)!$(document).on("topicName",!function!()!{!!!!!//..perform"some"behaviour!});!!//"Equivalent"to"publish(topicName)!$(document).trigger("topicName");!!//"Equivalent"to"unsubscribe(topicName)!$(document).off("topicName");!!
  • 36. AMD  -­‐  Asynchronous  module  defini3on  define(module_id/*optional*/,[dependencies]/*optional*/,definitionfunction/*function-for-instantiating-the-module-or-object*/)!!!require(["foo","bar"],function(foo,bar){//-rest-of-your-code-herefoo.doSomething();});!
  • 37. Prolifera3on  of  MV*  frameworks  
  • 38. Prolifera3on  of  MV*  frameworks  •  Rich  internet  single  page  applica3ons  •  Data  Binding  •  Client  side  templates  •  Client-­‐Centric  or  Server-­‐Centric-­‐  that  is  the  ques3on.  
  • 39. •  Minify,  concatenate,  compress  •  Load  scripts  at  the  end  of  pages  •  Sta3c  code  analysis  using  Jslint/Jshint  •  Tes3ng  your  code  –  Jasmine,  Phantomjs  etc  
  • 40. References  
  • 41. Ques:ons?