Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Treating Javascriptophpobia

Treating Javascriptophpobia

Javascriptophpobia: “A persistent, abnormal, and irrational fear of Javascript that compels PHP developers to avoid it, despite the awareness and reassurance that it is not dangerous.” In this session, I will show you why that fear is irrational, and with any luck you will be cured from it. Starting from what we all know best, PHP, we’ll have a look at how certain concepts we already know, translate back to Javascript. During this session, we will not concentrate on the syntax of the building blocks that constitute the great Javascript language, but rather on the concepts and semantics of certain techniques. Once we know and understand these concepts, we’ll end with some best practices for writing neat and structured Javascript. This treatment is highly recommended for anyone who exhibits symptoms of severe Javascript dislike and aversion.

Tom Van Herreweghe

January 23, 2015
Tweet

More Decks by Tom Van Herreweghe

Other Decks in Programming

Transcript

  1. SCOPE The scope of a name binding – an association

    of a name to an entity, such as a variable – is the part of a computer program where the binding is valid: where the name can be used to refer to the entity.
  2. GLOBAL SCOPE $ f o o = " b a

    r " ; $ G L O B A L S [ " b a r " ] = " b a z " ; v a r _ d u m p ( $ f o o ) ; / / " b a r " v a r _ d u m p ( $ G L O B A L S [ ' f o o ' ] ) ; / / " b a r " v a r _ d u m p ( $ G L O B A L S [ ' b a r ' ] ) ; / / " b a z " v a r _ d u m p ( $ b a r ) ; / / " b a z "
  3. LOCAL SCOPE f u n c t i o n

    f o o ( ) { $ a = ' a ' ; } v a r _ d u m p ( $ a ) ; / / n u l l f o o ( ) ; v a r _ d u m p ( $ a ) ; / / s t i l l n u l l
  4. LOCAL SCOPE $ a = ' a ' ; f

    u n c t i o n b a r ( ) { v a r _ d u m p ( $ a ) ; / / n u l l } b a r ( ) ;
  5. LOCAL SCOPE $ a = ' a ' ; f

    u n c t i o n b a r ( ) { g l o b a l $ a ; v a r _ d u m p ( $ a ) ; / / " a " $ a = ' b b b b ' ; } b a r ( ) ; v a r _ d u m p ( $ a ) ; / / " b b b b "
  6. SUPERGLOBALS v a r _ d u m p (

    $ _ S E R V E R ) ; / / S e r v e r & e x e c u t i o n e n v i n f o r m a t i o n v a r _ d u m p ( $ _ G E T ) ; / / H T T P G E T v a r i a b l e s v a r _ d u m p ( $ _ P O S T ) ; / / H T T P P O S T v a r i a b l e s v a r _ d u m p ( $ _ C O O K I E ) ; / / H T T P c o o k i e s v a r _ d u m p ( $ _ R E Q U E S T ) ; / / _ G E T + _ P O S T + _ C O O K I E v a r _ d u m p ( $ _ F I L E S ) ; / / H T T P F i l e U p l o a d v a r i a b l e s v a r _ d u m p ( $ _ S E S S I O N ) ; / / S e s s i o n i n f o r m a t i o n v a r _ d u m p ( $ _ E N V ) ; / / E n v i r o n m e n t v a r i a b l e s v a r _ d u m p ( $ G L O B A L S ) ;
  7. BLOCK SCOPE $ a = ' a a ' ;

    i f ( t r u e ) { v a r _ d u m p ( $ a ) ; / / " a a " $ b = ' b b ' ; } v a r _ d u m p ( $ b ) ; / / " b b " d o { v a r _ d u m p ( $ a ) ; / / " a a " v a r _ d u m p ( $ b ) ; / / " b b " $ d = ' d d ' ; b r e a k ; } w h i l e ( t r u e ) ; v a r _ d u m p ( $ d ) ; / / " d d " There is no "block" scope
  8. GLOBAL SCOPE c o n s o l e .

    l o g ( t h i s = = = w i n d o w ) ; / / t r u e / / i n n o d e j s : c o n s o l e . l o g ( t h i s = = = g l o b a l ) ; / / t r u e v a r p h p = " a w e s o m e " ; / / P r e f e r r e d ! p h p = " a w e s o m e " ; t h i s . p h p = " a w e s o m e " ; w i n d o w . p h p = " a w e s o m e " ;
  9. LOCAL SCOPE f u n c t i o n

    f o o ( ) { v a r a = " a " ; } c o n s o l e . l o g ( a ) ; / / R e f e r e n c e E r r o r f o o ( ) ; c o n s o l e . l o g ( a ) ; / / R e f e r e n c e E r r o r
  10. LOCAL SCOPE v a r a = " a "

    ; f u n c t i o n b a r ( ) { c o n s o l e . l o g ( a ) ; / / " a " } b a r ( ) ;
  11. LOCAL SCOPE v a r a = " a "

    ; f u n c t i o n f o o ( ) { v a r b = " b " ; f u n c t i o n b a r ( ) { c o n s o l e . l o g ( a ) ; c o n s o l e . l o g ( b ) ; v a r c = " c " ; } c o n s o l e . l o g ( c ) ; / / R e f e r e n c e E r r o r r e t u r n b a r ( ) ; } c o n s o l e . l o g ( b ) ; / / R e f e r e n c e E r r o r c o n s o l e . l o g ( c ) ; / / R e f e r e n c e E r r o r f o o ( ) ;
  12. BLOCK SCOPE v a r a = ' a a

    ' ; i f ( t r u e ) { c o n s o l e . l o g ( a ) ; / / " a a " v a r b = ' b b ' ; } c o n s o l e . l o g ( b ) ; / / " b b " d o { c o n s o l e . l o g ( a ) ; / / " a a " c o n s o l e . l o g ( b ) ; / / " b b " v a r c = ' c c ' ; b r e a k ; } w h i l e ( t r u e ) ; c o n s o l e . l o g ( c ) ; / / " c c " There is no block scope... yet! (ECMAScript >= 6)
  13. SCOPE IN A NUTSHELL PHP JS Global scope script window

    Local scope function function Block scope no ES >=6 Bubbles separate parent-child Access g l o b a l local -> local parent -> child local -> local
  14. PRIORITY v a r a = " a " ;

    f u n c t i o n f o o ( ) { v a r a = " b " ; f u n c t i o n b a r ( ) { c o n s o l e . l o g ( a ) ; / / " b " c o n s o l e . l o g ( w i n d o w . a ) ; / / " a " } r e t u r n b a r ( ) ; } f o o ( ) ; Local > Global
  15. HOISTING - VARIABLES $ a = " a " ;

    v a r _ d u m p ( $ a ) ; / / " a " v a r _ d u m p ( $ b ) ; / / n u l l v a r _ d u m p ( i s s e t ( $ b ) ) ; / / f a l s e $ b = " b " ;
  16. HOISTING - VARIABLES v a r f o o =

    " b a r " ; c o n s o l e . l o g ( f o o ) ; / / " b a r " c o n s o l e . l o g ( j s ) ; / / u n d e f i n e d v a r j s = " a w e s o m e " ; c o n s o l e . l o g ( p h p ) ; / / R e f e r e n c e E r r o r
  17. HOISTING - FUNCTIONS f u n c t i o

    n f o o ( ) { e c h o ' F o o i s e x e c u t e d ' ; } f o o ( ) ; / / " F o o i s e x e c u t e d " b a r ( ) ; / / " B a r i s e x e c u t e d " f u n c t i o n b a r ( ) { e c h o ' B a r i s e x e c u t e d ' ; } Functions need not be defined before they are referenced, except when a function is conditionally defined
  18. HOISTING - FUNCTIONS m y F u n c t

    i o n ( ) ; / / " I a m c a l l e d " f u n c t i o n m y F u n c t i o n ( ) { c o n s o l e . l o g ( " I a m c a l l e d " ) ; }
  19. WHAT IS HOISTING? c o n s o l e

    . l o g ( j s ) ; v a r j s = " a w e s o m e " ; / / r e - w r i t t e n : v a r j s ; c o n s o l e . l o g ( j s ) ; j s = " a w e s o m e " ;
  20. TL;DR - SCOPE 1. Global scope (window / global) 2.

    Local scope (function) 3. Priority (Local > Global) 4. Hoisting (declaration <> assignment)
  21. DECLARATION (1) / / f u n c t i

    o n l i t e r a l d e c l a r a t i o n f u n c t i o n f o o ( / * o p t i o n a l p a r a m e t e r s * / ) { / * f u n c t i o n b o d y * / r e t u r n t r u e ; / / o p t i o n a l r e t u r n s t a t e m e n t } c o n s o l e . l o g ( f o o ( ) ) ; / / t r u e c o n s o l e . l o g ( w i n d o w . f o o ( ) ) ; / / t r u e c o n s o l e . l o g ( f o o . n a m e ) ; / / " f o o " Function literal
  22. DECLARATION (2) / / f u n c t i

    o n e x p r e s s i o n v a r b a r = f u n c t i o n ( / * o p t i o n a l p a r a m e t e r s * / ) { r e t u r n t r u e ; } ; c o n s o l e . l o g ( b a r ( ) ) ; / / t r u e c o n s o l e . l o g ( b a r . n a m e ) ; / / < e m p t y s t r i n g > Function expression (or "Inline function") (or "Anonymous function") (not a closure)
  23. DECLARATION (3) / / i n l i n e

    n a m e d f u n c t i o n v a r b a z = f u n c t i o n s c o o b y d o o ( ) { r e t u r n t r u e ; } ; c o n s o l e . l o g ( b a z ( ) ) ; / / t r u e c o n s o l e . l o g ( b a z . n a m e ) ; / / " s c o o b y d o o " c o n s o l e . l o g ( s c o o b y d o o ( ) ) ; / / R e f e r e n c e E r r o r Inline named function (also not a closure)
  24. DECLARATION - PHP / / f u n c t

    i o n l i t e r a l d e c l a r a t i o n f u n c t i o n f o o ( ) { r e t u r n t r u e ; } v a r _ d u m p ( f o o ( ) ) ; / / t r u e Function literal
  25. DECLARATION - PHP / / a n o n y

    m o u s f u n c t i o n $ b a r = f u n c t i o n ( ) { r e t u r n t r u e ; } ; v a r _ d u m p ( $ b a r ( ) ) ; / / t r u e v a r _ d u m p ( g e t t y p e ( $ b a r ) ) ; / / o b j e c t v a r _ d u m p ( g e t _ c l a s s ( $ b a r ) ) ; / / " C l o s u r e " Function expression (not *really* a closure)
  26. DECLARATION - PHP / / i n l i n

    e n a m e d f u n c t i o n ? $ b a z = f u n c t i o n b a z i n g a ( ) { / / S y n t a x e r r o r r e t u r n t r u e ; } ; v a r _ d u m p ( $ b a z ( ) ) ;
  27. INVOCATION (1) / / f u n c t i

    o n i n v o c a t i o n f u n c t i o n f o o ( ) { c o n s o l e . l o g ( t h i s = = = w i n d o w ) ; / / t r u e } f o o ( ) ; Function invocation
  28. INVOCATION (2) / / m e t h o d

    i n v o c a t i o n v a r b a r = { a f t e r S u b m i t : f u n c t i o n ( ) { c o n s o l e . l o g ( t h i s = = = b a r ) ; / / t r u e } } ; b a r . a f t e r S u b m i t ( ) ; Method invocation
  29. INVOCATION (3) / / c o n s t r

    u c t o r i n v o c a t i o n f u n c t i o n C a r ( b r a n d ) { t h i s . m a k e = b r a n d ; c o n s o l e . l o g ( t h i s ) ; } v a r b m w = n e w C a r ( ' b m w ' ) ; / / C a r { m a k e = " b m w " } v a r f o r d = n e w C a r ( ' f o r d ' ) ; / / C a r { m a k e = " f o r d " } Constructor invocation
  30. INVOCATION (4) / / c a l l / a

    p p l y i n v o c a t i o n ( 1 ) v a r a i r p l a n e = { f l y : f u n c t i o n ( ) { c o n s o l e . l o g ( t h i s ) ; } } ; v a r f i g h t e r P l a n e = { t y p e : ' f i g h t e r ' } ; a i r p l a n e . f l y ( ) ; / / O b j e c t { f l y = f u n c t i o n ( ) } a i r p l a n e . f l y . c a l l ( f i g h t e r P l a n e ) ; / / O b j e c t { t y p e = " f i g h t e r " } Call / Apply invocation
  31. INVOCATION - PHP f u n c t i o

    n s u m ( $ a , $ b ) { r e t u r n $ a + $ b ; } v a r _ d u m p ( s u m ( 1 , 2 ) ) ; / / 3 v a r _ d u m p ( c a l l _ u s e r _ f u n c ( ' s u m ' , 1 , 2 ) ) ; / / 3 ~ c a l l v a r _ d u m p ( c a l l _ u s e r _ f u n c _ a r r a y ( ' s u m ' , [ 1 , 2 ] ) ) ; / / 3 ~ a p p l y
  32. INVOCATION - PHP / / s e t c o

    n t e x t $ f o o = f u n c t i o n ( ) { r e t u r n $ t h i s - > a + $ t h i s - > b ; } ; $ d a t a = n e w \ S t d C l a s s ( ) ; $ d a t a - > a = 1 ; $ d a t a - > b = 2 ; $ n e w F o o = C l o s u r e : : b i n d ( $ f o o , $ d a t a ) ; v a r _ d u m p ( $ n e w F o o ( ) ) ; / / 3 $ n e w e r F o o = $ f o o - > b i n d T o ( $ d a t a ) ; v a r _ d u m p ( $ n e w e r F o o ( ) ) ; / / 3
  33. NAMED FUNCTIONS / / n ! = n + (

    n - 1 ) ! v a r f a c t o r i a l = f u n c t i o n ( x ) { r e t u r n ( x = = = 1 ) ? 1 : f a c t o r i a l ( x - 1 ) + x ; } ; c o n s o l e . l o g ( f a c t o r i a l ( 4 ) ) ; / / 1 0 ( = 4 + 3 + 2 + 1 )
  34. NAMED FUNCTIONS / / c o p y r e

    f e r e n c e t o a n o n y m o u s f u n c t i o n , / / a n d d e s t r o y t h e o r i g i n a l r e f e r e n c e t o i t v a r a l s o F a c t o r i a l = f a c t o r i a l ; f a c t o r i a l = n u l l ; c o n s o l e . l o g ( a l s o F a c t o r i a l ( 4 ) ) ; / / T y p e E r r o r !
  35. NAMED FUNCTIONS / / b e t t e r

    s o l u t i o n : v a r m y F a c = f u n c t i o n f a c ( x ) { r e t u r n ( x = = = 1 ) ? 1 : f a c ( x - 1 ) + x ; } ; c o n s o l e . l o g ( m y F a c ( 4 ) ) ; / / 1 0 v a r a l s o M y F a c = m y F a c ; m y F a c = n u l l ; c o n s o l e . l o g ( a l s o M y F a c ( 4 ) ) ; / / 1 0
  36. OVERLOADING / / P r e m i s e

    f u n c t i o n s u m ( a , b ) { r e t u r n a + b ; } c o n s o l e . l o g ( s u m ( 1 , 2 ) ) ; / / 3 c o n s o l e . l o g ( s u m ( 4 , 6 , 7 ) ) ; / / 1 0 ( w h a t h a p p e n e d t o 7 ? )
  37. OVERLOADING / / S o l u t i o

    n f u n c t i o n s u m 2 ( ) { / / n o n a m e d a r g u m e n t s n e e d e d a n y m o r e v a r r e s u l t = 0 ; f o r ( v a r i = 0 ; i < a r g u m e n t s . l e n g t h ; i + + ) { r e s u l t + = a r g u m e n t s [ i ] ; } r e t u r n r e s u l t ; } ; c o n s o l e . l o g ( s u m 2 ( 4 , 6 , 7 ) ) ; / / 1 7 c o n s o l e . l o g ( s u m 2 ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ) ) ; / / 4 5
  38. TL;DR - FUNCTIONS 1. 3 ways of declaring a function

    2. 4 ways of invoking a function 3. Named functions (recursion) 4. Overloading
  39. CLOSURES A closure is a function or reference to a

    function together with a referencing environment A closure enables a function to access non-local variables even when invoked outside its immediate lexical scope.
  40. EXAMPLE (1) v a r f o o = '

    f o o ' ; f u n c t i o n c l i c k ( ) { c o n s o l e . l o g ( f o o ) ; } c l i c k ( ) ; / / " f o o "
  41. EXAMPLE (2) v a r e x e c u

    t e L a t e r ; f u n c t i o n b a r ( ) { v a r m i c k e y = ' m o u s e ' ; e x e c u t e L a t e r = f u n c t i o n ( ) { c o n s o l e . l o g ( m i c k e y ) ; } } c o n s o l e . l o g ( t y p e o f e x e c u t e L a t e r ) ; / / u n d e f i n e d b a r ( ) ; c o n s o l e . l o g ( t y p e o f e x e c u t e L a t e r ) ; / / f u n c t i o n e x e c u t e L a t e r ( ) ; / / " m o u s e "
  42. EXAMPLE (PHP) $ a m o u n t =

    0 ; $ c l i c k = f u n c t i o n ( ) u s e ( & $ a m o u n t ) { $ a m o u n t + + ; } ; v a r _ d u m p ( $ a m o u n t ) ; / / 0 $ c l i c k ( ) ; v a r _ d u m p ( $ a m o u n t ) ; / / 1
  43. USAGE: PRIVATE VARIABLES f u n c t i o

    n S o l d i e r ( ) { v a r r a n k ; t h i s . s e t R a n k = f u n c t i o n ( n a m e ) { r a n k = n a m e ; } ; t h i s . g e t R a n k = f u n c t i o n ( ) { r e t u r n r a n k ; } ; } v a r c o r p o r a l = n e w S o l d i e r ( ) ; c o r p o r a l . s e t R a n k ( ' c o r p o r a l ' ) ; c o n s o l e . l o g ( c o r p o r a l . r a n k ) ; / / u n d e f i n e d c o n s o l e . l o g ( c o r p o r a l . g e t R a n k ( ) ) ; / / " c o r p o r a l "
  44. DEFINITION / / C a l l o p e

    r a t o r : ( ) ( / * . . . * / ) ( ) ;
  45. DEFINITION ( f u n c t i o n

    ( ) { v a r f o o = ' f o o ' ; } ) ( ) ; c o n s o l e . l o g ( f o o ) ; / / R e f e r e n c e E r r o r Temporary scope with private variables
  46. USAGE ( f u n c t i o n

    ( $ ) { $ ( ' a ' ) . b i n d ( ' c l i c k ' , f u n c t i o n ( ) { a l e r t ( ' I w a s c l i c k e d ' ) ; } ) ; } ) ( j Q u e r y ) ; Aliasing variables
  47. USAGE / / P r e m i s e

    : k e e p t r a c k o f # r u n s v a r r u n s = 0 ; v a r t i m e r = s e t I n t e r v a l ( f u n c t i o n ( ) { r u n s + + ; c o n s o l e . l o g ( r u n s ) ; i f ( r u n s > = 1 0 ) { c l e a r I n t e r v a l ( t i m e r ) ; } } , 5 0 0 ) ; Tidy global scope
  48. USAGE / / B e t t e r w

    a y o f k e e p i n g t r a c k : v a r t i m e r = s e t I n t e r v a l ( ( f u n c t i o n ( ) { v a r r u n s = 0 ; r e t u r n f u n c t i o n ( ) { r u n s + + ; c o n s o l e . l o g ( r u n s ) ; i f ( r u n s > = 1 0 ) { c l e a r I n t e r v a l ( t i m e r ) ; } } ; } ) ( ) , 5 0 0 ) ; Clean global scope
  49. TL;DR - IIFE'S 1. Temporary Scope 2. Private variables 3.

    Usage: Structuring code (aliasing) 4. Usage: Tidy Scope
  50. CREDITS - IMAGES 1. Sleeping kid - https://flic.kr/p/5PcP7r 2. Ju-jitsu

    feet - Jachim Coudenys 3. Wolf spider - https://flic.kr/p/6hULjn 4. Javascript screen - https://flic.kr/p/5Y1z6v 5. Lobotomy - Wikimedia Commons 6. Bubbles 1 - https://flic.kr/p/4Ljnww 7. Cranes over Dubai - https://flic.kr/p/rFgym 8. Overloading - https://flic.kr/p/xEwLt 9. Currying - https://flic.kr/p/9ZGhy6 10. YDKJS books - O'Reilly 11. Secrets of the Javascript Ninja - Amazon.com