Javascript patterns
Upcoming SlideShare
Loading in...5
×
 

Javascript patterns

on

  • 799 views

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.

Statistics

Views

Total Views
799
Views on SlideShare
782
Embed Views
17

Actions

Likes
1
Downloads
17
Comments
0

2 Embeds 17

https://www.linkedin.com 9
http://www.linkedin.com 8

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Javascript patterns Javascript patterns Presentation Transcript

  • JavaScript  -­‐  What’s  in  the  language?  
  • 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  
  • Good  Parts  •  Lambda  •  Dynamic  objects  •  Loose  typing  •  Object  literals   View slide
  • Bad  Parts  •  Global  Variables  •  +  adds  and  concatenates  •  Semicolon  inser3on  •  typeof  •  with  and  eval  •  ==  and  !=  •  false,  null,  undefined,  NaN   View slide
  • General  Pa8erns  
  • 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"!
  • 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;!! }!
  • ! //"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!! }!
  • 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...!! }!
  • Namespacing  ! //!unsafe!! var!MYAPP!=!{};!! //!better!! if!(typeof!MYAPP!===!"undefined")!{!! ! var!MYAPP!=!{};!! }!! //!or!shorter!! var!MYAPP!=!MYAPP!||!{};!
  • ! 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!
  • 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!! }!
  • 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]);!
  • /*#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);!
  • 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!()!{!! ! };!! }!
  • ! //"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!" "*/!
  • Automa3c  semicolon  inser3on  //antipattern!return!{!!!!!status:!true!};!!//preferred!return{!!!!!status:!true!};!!
  • Func:on  Pa8erns  
  • 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!
  • 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!
  • Literals,  Constructors  and  Object  crea:on  Pa8erns  
  • 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"!
  • 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"!
  • ! //!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;!
  • /*!#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"!
  • 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// / / / };// / / }());/!
  • Code  Reuse  Pa8erns  
  • 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"!
  • //"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"!
  • Augmen3ng  built-­‐in  Prototypes  if!(typeof!Object.prototype.myMethod!!==!"function")!{!! Object.prototype.myMethod!=!function!()!{!! ! //"implementation...!! };!}!
  • Design  Pa8erns  
  • 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  
  • Composite  //"Single"elements!$("#singleItem").addClass("active");!$("#container").addClass("active");!!//"Collections"of"elements!$("div").addClass("active");!$(".item").addClass("active");!$("input").addClass("active");!!
  • 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);!!
  • 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");!!
  • 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();});!
  • Prolifera3on  of  MV*  frameworks  
  • Prolifera3on  of  MV*  frameworks  •  Rich  internet  single  page  applica3ons  •  Data  Binding  •  Client  side  templates  •  Client-­‐Centric  or  Server-­‐Centric-­‐  that  is  the  ques3on.  
  • •  Minify,  concatenate,  compress  •  Load  scripts  at  the  end  of  pages  •  Sta3c  code  analysis  using  Jslint/Jshint  •  Tes3ng  your  code  –  Jasmine,  Phantomjs  etc  
  • References  
  • Ques:ons?