Monday, November 15, 2010
Doug Hendricks               Solutions Architect               Sencha ServicesMonday, November 15, 2010
ECMA      Scope Soup                ‘From the can’,               alternate recipes,                  and puzzles.Monday, ...
On the menu:                   • ECMA Javascript variables and scope                   • In the can: Activation objects, s...
Global Variables                        Global variables - exist throughout the life of a                        script. A...
What is the global                             object(namespace)?                            Browsers, GreaseMonkey : wind...
Global Variables                      <script type="text/javascript">                        globalB = 4;                 ...
Local Variables                            Local variables - survive only as long as the                            Functi...
Something wrong here?                            <script type="text/javascript">                               var globalA...
Something wrong here?                            <script type="text/javascript">                               var globalA...
Something wrong here?                            <script type="text/javascript">                               var globalA...
<script type="text/javascript">                               var globalA,                                   say = console...
introducing...                             activation objects,                                scope chain,                ...
Execution context initialized containing a                            ‘root’ or global object.Monday, November 15, 2010
Execution context initialized containing a                            ‘root’ or global object.      <script type="text/jav...
next, an activation object is prepended to the                   scope-chain by first scanning the function body           ...
next, an activation object is prepended to the                   scope-chain by first scanning the function body           ...
Identifier resolution: get me ‘say’ ! (the hunt                            begins)                                         ...
Identifier resolution: get me ‘say’ ! (the hunt                            begins)                                         ...
Identifier resolution: get me ‘say’ ! (the hunt                            begins)                                         ...
Now, on to the function argument: ‘a’                                                           Scope chain       function...
Now, on to the function argument: ‘a’                                                           Scope chain       function...
Now, on to assignment...                                                       Scope chain       function doIt ( ) {      ...
Now, on to assignment...                                                       Scope chain       function doIt ( ) {      ...
When function doIt is completed, it’s                            execution context (scope chain) is destroyed:           d...
When function doIt is completed, it’s                            execution context (scope chain) is destroyed:           d...
Monday, November 15, 2010
Extra fat ?                            (Scope Chain Augmentation)Monday, November 15, 2010
(Scope Chain Augmentation)Monday, November 15, 2010
Scope Chain Augmentation                  The big offenders:Monday, November 15, 2010
Scope Chain Augmentation                  The big offenders:                            Closures                          ...
Scope Chain Augmentation                                 Function Closures    var trimString = function () {       var reR...
Scope Chain Augmentation                                 Function Closures    var trimString = function () {              ...
Scope Chain Augmentation                                 Function Closures    var trimString = function () {              ...
Scope Chain Augmentation                                          Function Closures             function puffEmUp () {    ...
Scope Chain Augmentation                                          Function Closures             function puffEmUp () {    ...
Monday, November 15, 2010
Even more fat !?                                (with Clause)Monday, November 15, 2010
Monday, November 15, 2010
Scope Chain Augmentation                                                        ‘with’ Clause             function puffEmU...
Scope Chain Augmentation                                                        ‘with’ Clause             function puffEmU...
Scope Chain Augmentation                                                        ‘with’ Clause             function puffEmU...
Monday, November 15, 2010
Let’s just eat Lard !                                (catch in try/catch)Monday, November 15, 2010
Monday, November 15, 2010
Scope Chain Augmentation                                              catch block          doc.on({             click : fu...
Scope Chain Augmentation                                              catch block          doc.on({             click : fu...
Scope Chain Augmentation                                              catch block                                         ...
Optimizations          function puffEmUp () {             var els = Ext.select(div),                 doc = Ext.getDoc();  ...
Optimizations                        Expensive          function puffEmUp () {             var els = Ext.select(div),     ...
Optimizations                        Expensive                                   Better                                   ...
Optimize Further                                                           function puffEmUp () {                         ...
Optimize Further                                                           function puffEmUp () {                         ...
Leverage Execution Context            function puffEmUp () {                 var    E = Ext,                       els = E...
Leverage Execution Context            function puffEmUp () {                 var    E = Ext,                       els = E...
Recommendations                            Declare frequently used function variables as locals.                          ...
Why is this important at                         all?Monday, November 15, 2010
trivia time!Monday, November 15, 2010
trivia time!                         Can you guess how many                    function definitions there are in the       ...
Can you guess how many                      function definitions there are in the                              Ext 3.3 fram...
Can you guess how many                      function definitions there are in the                              Ext 3.3 fram...
Can you guess how many                      function definitions there are in the                              Ext 3.3 fram...
Can you guess how many                      function definitions there are in the                              Ext 3.3 fram...
Can you guess how many                      function definitions there are in the                              Ext 3.3 fram...
Can you guess how many                      function definitions there are in the                              Ext 3.3 fram...
If you guessed:                            b: at least 5300...Monday, November 15, 2010
If you guessed:                            b: at least 5300...Monday, November 15, 2010
If you guessed:                            b: at least 5300...                             You’re Correct!              bu...
Common Mistakes and BottlenecksMonday, November 15, 2010
Where did it go?                            <script type="text/javascript">                               function doIt ( ...
Where did it go?                                       <script type="text/javascript">   <script type="text/javascript">  ...
Where did it go?                                       <script type="text/javascript">   <script type="text/javascript">  ...
Identifier Resolution                                  Mayhem!                   var getAddress = function(){              ...
Identifier Resolution                                  Mayhem!                   var getAddress = function(){              ...
Identifier Resolution                                  Optimized!                            var getAddress = function () {...
Iteration (with calories)                       Function-based                        Ext.each (iterable, function)       ...
Iteration (with calories)                       Function-based                        Ext.each (iterable, function)       ...
Traditional event binding                        strategiesMonday, November 15, 2010
Classic Quandary        {        xtype: ‘grid’,        store : ‘storeId’,        buttons : [{              text : ‘Remove ...
{             xtype: ‘grid’,             store : ‘storeId’,             initComponent : function(){ /   /template method  ...
Bring your desired scope into context             {                                    (without sub-classing)             ...
Poor-man’s Message Bus                            Revised version of Ext.util.Observable class                            ...
(function(){                   Ext.extend(                       Ext.ux.MsgBus = function(config){                        ...
Why not as a singleton?                            Poor candidates for Unit testing as ‘state’ is                         ...
Basic ux.MsgBus sample         Ext.ns(your);         your.bus = new Ext.ux.MsgBus();         your.bus.subscribe(test,     ...
Multi-Channel            Ext.namespace(your);            your.bus = {               channels: {    // slots, topics (call ...
{             xtype: ‘grid’,             store : ‘storeId’,             initComponent : function(){ /   /template method  ...
Questions ?Monday, November 15, 2010
Thank You!                            Hackathon : 4:30pm                            Enjoy the remainder of                ...
Upcoming SlideShare
Loading in …5
×

JavaScript: Advanced Scoping & Other Puzzles

5,308 views

Published on

In this session, we'll review the fundamentals of Javascript variable scope and common "execution context" (scope) challenges associated with early/late binding of event handlers, specifically within complex Ext JS layouts. We'll also bring several patterns (namespaced references, Function closures, inline references, ref/refOwner, and the "Poor-man's message bus") to bear on the bowl of soup we call "scope."

Published in: Technology
1 Comment
6 Likes
Statistics
Notes
No Downloads
Views
Total views
5,308
On SlideShare
0
From Embeds
0
Number of Embeds
222
Actions
Shares
0
Downloads
164
Comments
1
Likes
6
Embeds 0
No embeds

No notes for slide

JavaScript: Advanced Scoping & Other Puzzles

  1. 1. Monday, November 15, 2010
  2. 2. Doug Hendricks Solutions Architect Sencha ServicesMonday, November 15, 2010
  3. 3. ECMA Scope Soup ‘From the can’, alternate recipes, and puzzles.Monday, November 15, 2010
  4. 4. On the menu: • ECMA Javascript variables and scope • In the can: Activation objects, scope chains, name resolution, and execution context • Too much salt (common mistakes) • Ext Observable binding contexts • Alternate binding approaches for Ext ComponentsMonday, November 15, 2010
  5. 5. Global Variables Global variables - exist throughout the life of a script. Also considered public, they are: those NOT declared within a function block declared ANYWHERE in your script without the var keyword <script type="text/javascript"> globalB = 4; var globalA = 3, say = console.log; </script>Monday, November 15, 2010
  6. 6. What is the global object(namespace)? Browsers, GreaseMonkey : window HTML5 Workers, Node.Js : globalMonday, November 15, 2010
  7. 7. Global Variables <script type="text/javascript"> globalB = 4; var globalA = 3, say = console.log; </script> or, referenced through the global object as: window.globalA window.sayMonday, November 15, 2010
  8. 8. Local Variables Local variables - survive only as long as the Function block they are declared in has an execution context. <script type="text/javascript"> var globalA, say = console.log; function doIt ( ) { var localA = 5; //local scope only } </script>Monday, November 15, 2010
  9. 9. Something wrong here? <script type="text/javascript"> var globalA, say = console.log, a = 4; doIt(); function doIt ( ) { say ( a ); var a = 5; say( ++a ); } </script>Monday, November 15, 2010
  10. 10. Something wrong here? <script type="text/javascript"> var globalA, say = console.log, a = 4; doIt(); function doIt ( ) { say ( a ); var a = 5; say( ++a ); } </script>Monday, November 15, 2010
  11. 11. Something wrong here? <script type="text/javascript"> var globalA, say = console.log, a = 4; doIt(); <- this can’t work! function doIt ( ) { say ( a ); <- this is 4, right? var a = 5; say( ++a ); } </script>Monday, November 15, 2010
  12. 12. <script type="text/javascript"> var globalA, say = console.log, a = 4; doIt(); <- sure it does, why? function doIt ( ) { say ( a ); <- undefined! why? var a = 5; say( ++a ); } </script>Monday, November 15, 2010
  13. 13. introducing... activation objects, scope chain, identifier resolutionMonday, November 15, 2010
  14. 14. Execution context initialized containing a ‘root’ or global object.Monday, November 15, 2010
  15. 15. Execution context initialized containing a ‘root’ or global object. <script type="text/javascript"> Scope chain var globalA, say = console.log, global a = 4; window : object doIt(); document : object function doIt ( ) { navigator : object say ( a ); a:4 doIt : function var a = 5; globalA : undefined say( ++a ); say : function } </script>Monday, November 15, 2010
  16. 16. next, an activation object is prepended to the scope-chain by first scanning the function body for local var’s: global window : object document : object navigator : object a:4 doIt : function globalA : undefinedMonday, November 15, 2010
  17. 17. next, an activation object is prepended to the scope-chain by first scanning the function body for local var’s: Scope chain doIt(); activation function doIt ( ) { arguments : [] say ( a ); this : window a : undefined var a = 5; say( ++a ); global } window : object document : object navigator : object thus, a new context is created a:4 for doIt, containing a local ‘a’ doIt : function globalA : undefinedMonday, November 15, 2010
  18. 18. Identifier resolution: get me ‘say’ ! (the hunt begins) Scope chain function doIt ( ) { activation say ( a ); arguments : [] var a = 5; this : window a : undefined say( ++a ); } global window : object document : object navigator : object a:4 say : functionMonday, November 15, 2010
  19. 19. Identifier resolution: get me ‘say’ ! (the hunt begins) Scope chain function doIt ( ) { activation say ( a ); arguments : [] var a = 5; local?, nope! this : window a : undefined say( ++a ); } global window : object document : object navigator : object a:4 say : functionMonday, November 15, 2010
  20. 20. Identifier resolution: get me ‘say’ ! (the hunt begins) Scope chain function doIt ( ) { activation say ( a ); arguments : [] var a = 5; local?, nope! this : window a : undefined say( ++a ); } global window : object document : object global has it! navigator : object a:4 say : functionMonday, November 15, 2010
  21. 21. Now, on to the function argument: ‘a’ Scope chain function doIt ( ) { activation arguments : [] say ( a ); this : window var a = 5; a : undefined say( ++a ); } global window : object document : object navigator : object a:4 say : functionMonday, November 15, 2010
  22. 22. Now, on to the function argument: ‘a’ Scope chain function doIt ( ) { activation arguments : [] say ( a ); <- prints: undefined this : window var a = 5; <- NOT 5! a : undefined say( ++a ); } global window : object document : object navigator : object a:4 say : functionMonday, November 15, 2010
  23. 23. Now, on to assignment... Scope chain function doIt ( ) { activation say ( a ); arguments : [] var a = 5; this : window say( ++a ); a : undefined } global window : object document : object navigator : object a:4 say : functionMonday, November 15, 2010
  24. 24. Now, on to assignment... Scope chain function doIt ( ) { activation say ( a ); arguments : [] var a = 5; local? yes, set it! this : window say( ++a ); a : undefined a:5 } global window : object document : object navigator : object a:4 and so on... say : functionMonday, November 15, 2010
  25. 25. When function doIt is completed, it’s execution context (scope chain) is destroyed: doIt(); Scope chain function doIt ( ) { activation say ( a ); arguments : [] var a = 5; this : window say( ++a ); a:5 } global window : object document : object navigator : object a:4 say : functionMonday, November 15, 2010
  26. 26. When function doIt is completed, it’s execution context (scope chain) is destroyed: doIt(); function doIt ( ) { say ( a ); var a = 5; say( ++a ); } and life continues, until the next function block...Monday, November 15, 2010
  27. 27. Monday, November 15, 2010
  28. 28. Extra fat ? (Scope Chain Augmentation)Monday, November 15, 2010
  29. 29. (Scope Chain Augmentation)Monday, November 15, 2010
  30. 30. Scope Chain Augmentation The big offenders:Monday, November 15, 2010
  31. 31. Scope Chain Augmentation The big offenders: Closures with Clause catch clause of try/catchMonday, November 15, 2010
  32. 32. Scope Chain Augmentation Function Closures var trimString = function () { var reReplace = /^s+|s+$/g; return ( function (str){ return str.replace(reReplace, ‘’); } ); }( ); <- create the closure global window : object document : object navigator : objectMonday, November 15, 2010
  33. 33. Scope Chain Augmentation Function Closures var trimString = function () { activation var reReplace = /^s+|s+$/g; arguments : [str] this : window return ( function (str){ return str.replace(reReplace, ‘’); activation arguments : [] } ); this : window }( ); <- create the closure reReplace : RegExp global window : object document : object navigator : objectMonday, November 15, 2010
  34. 34. Scope Chain Augmentation Function Closures var trimString = function () { activation var reReplace = /^s+|s+$/g; arguments : [str] this : window return ( function (str){ return str.replace(reReplace, ‘’); activation arguments : [] } ); this : window }( ); <- create the closure reReplace : RegExp Closures will always have 3 global window : object scope chain members, document : object navigator : object minimum!Monday, November 15, 2010
  35. 35. Scope Chain Augmentation Function Closures function puffEmUp () { var els = Ext.select(div), doc = Ext.getDoc(); els.addClass(puff); doc.on({ click : function(e, target){ els.removeClass(‘puff’); els.highlight(); }, ‘delegate’ : div.puff, ‘single’ : true global }); window : object } document : object navigator : objectMonday, November 15, 2010
  36. 36. Scope Chain Augmentation Function Closures function puffEmUp () { activation var els = Ext.select(div), arguments : [e, target] doc = Ext.getDoc(); this : Ext.Element els.addClass(puff); activation doc.on({ arguments : [] click : function(e, target){ this : window els.removeClass(‘puff’); els : Ext.CompositeEl... els.highlight(); doc : Ext.Element }, ‘delegate’ : div.puff, ‘single’ : true global }); window : object } document : object navigator : objectMonday, November 15, 2010
  37. 37. Monday, November 15, 2010
  38. 38. Even more fat !? (with Clause)Monday, November 15, 2010
  39. 39. Monday, November 15, 2010
  40. 40. Scope Chain Augmentation ‘with’ Clause function puffEmUp () { var els = Ext.select(div), doc = Ext.getDoc(); els.addClass(puff); doc.on({ click : function(e, target){ with (els) { removeClass(‘puff’); highlight(); } }, ‘delegate’ : div.puff, ‘single’ : true }); }Monday, November 15, 2010
  41. 41. Scope Chain Augmentation ‘with’ Clause function puffEmUp () { var els = Ext.select(div), doc = Ext.getDoc(); els.addClass(puff); doc.on({ activation click : function(e, target){ arguments : [e, target] with (els) { removeClass(‘puff’); activation highlight(); arguments : [] } }, global ‘delegate’ : div.puff, ‘single’ : true window : object }); }Monday, November 15, 2010
  42. 42. Scope Chain Augmentation ‘with’ Clause function puffEmUp () { var els = Ext.select(div), variable doc = Ext.getDoc(); els : Ext.CompositeEl... els.addClass(puff); doc.on({ activation click : function(e, target){ arguments : [e, target] with (els) { removeClass(‘puff’); activation highlight(); arguments : [] } }, global ‘delegate’ : div.puff, ‘single’ : true window : object }); }Monday, November 15, 2010
  43. 43. Monday, November 15, 2010
  44. 44. Let’s just eat Lard ! (catch in try/catch)Monday, November 15, 2010
  45. 45. Monday, November 15, 2010
  46. 46. Scope Chain Augmentation catch block doc.on({ click : function(e, target){ try{ with (els) { removeClass(‘puff’); highlight(); } } catch( err ) { Ext.MessageBox.alert(‘Ooops’); } },Monday, November 15, 2010
  47. 47. Scope Chain Augmentation catch block doc.on({ click : function(e, target){ try{ activation with (els) { arguments : [e, target] removeClass(‘puff’); highlight(); } activation } catch( err ) { arguments : [] Ext.MessageBox.alert(‘Ooops’); } global }, window : objectMonday, November 15, 2010
  48. 48. Scope Chain Augmentation catch block variable arguments : [err] doc.on({ click : function(e, target){ try{ activation with (els) { arguments : [e, target] removeClass(‘puff’); highlight(); } activation } catch( err ) { arguments : [] Ext.MessageBox.alert(‘Ooops’); } global }, window : objectMonday, November 15, 2010
  49. 49. Optimizations function puffEmUp () { var els = Ext.select(div), doc = Ext.getDoc(); els.addClass(puff); doc.on({ click : function(e, target){ els.removeClass(‘puff’); els.highlight(); }, ‘delegate’ : div.puff, ‘single’ : true }); }Monday, November 15, 2010
  50. 50. Optimizations Expensive function puffEmUp () { var els = Ext.select(div), doc = Ext.getDoc(); els.addClass(puff); doc.on({ click : function(e, target){ els.removeClass(‘puff’); els.highlight(); }, ‘delegate’ : div.puff, ‘single’ : true }); }Monday, November 15, 2010
  51. 51. Optimizations Expensive Better function puffEmUp () { function puffEmUp () { var els = Ext.select(div), var E = Ext, doc = Ext.getDoc(); els = E.select(div); els.addClass(puff); els.addClass(puff); doc.on({ E.getDoc().on({ click : function(e, target){ click : function(e, target){ els.removeClass(‘puff’); els.highlight(); var collect = els; }, collect.removeClass(‘puff’); ‘delegate’ : div.puff, collect.highlight(); ‘single’ : true }, }); ‘delegate’ : div.puff, } ‘single’ : true }); }Monday, November 15, 2010
  52. 52. Optimize Further function puffEmUp () { var E = Ext, els = E.select(div); function puffEmUp () { var E = Ext, els.addClass(puff); E.getDoc().on({ els = E.select(div); click : function(e, target){ try{ els.addClass(puff); this.removeClass(‘puff’); E.getDoc().on({ this.highlight(); click : function(e, target){ } catch (err) { / a compromise / var collect = els; E.MessageBox.alert(‘Oops’); collect.removeClass(‘puff’); } collect.highlight(); }, }, ‘delegate’ : div.puff, ‘scope’ : els, ‘single’ : true ‘delegate’ : div.puff, }); ‘single’ : true } }); }Monday, November 15, 2010
  53. 53. Optimize Further function puffEmUp () { Better var E = Ext, els = E.select(div); function puffEmUp () { var E = Ext, els.addClass(puff); E.getDoc().on({ els = E.select(div); click : function(e, target){ try{ els.addClass(puff); this.removeClass(‘puff’); E.getDoc().on({ this.highlight(); click : function(e, target){ } catch (err) { / a compromise / var collect = els; E.MessageBox.alert(‘Oops’); collect.removeClass(‘puff’); } collect.highlight(); }, }, ‘delegate’ : div.puff, ‘scope’ : els, ‘single’ : true ‘delegate’ : div.puff, }); ‘single’ : true } }); }Monday, November 15, 2010
  54. 54. Leverage Execution Context function puffEmUp () { var E = Ext, els = E.select(div); els.addClass(puff); E.getDoc().on({ click : function(e, target){ try{ this.removeClass(‘puff’); this.highlight(); } catch (err) { / a compromise / E.MessageBox.alert(‘Oops’); } }, ‘scope’ : els, ‘delegate’ : div.puff, ‘single’ : true }); }Monday, November 15, 2010
  55. 55. Leverage Execution Context function puffEmUp () { var E = Ext, els = E.select(div); els.addClass(puff); Replace scope- E.getDoc().on({ click : function(e, target){ chain traversal try{ this.removeClass(‘puff’); with a single this.highlight(); context (this) } catch (err) { / a compromise / prototype } E.MessageBox.alert(‘Oops’); search. }, ‘scope’ : els, ‘delegate’ : div.puff, ‘single’ : true }); }Monday, November 15, 2010
  56. 56. Recommendations Declare frequently used function variables as locals. Promote frequently used globals UP the scope chain (creating local references to them as necessary) Use closures and try/catch handlers sparingly. Forget about the ‘with’ clause! (deprecated in ECMA Javascript 5)Monday, November 15, 2010
  57. 57. Why is this important at all?Monday, November 15, 2010
  58. 58. trivia time!Monday, November 15, 2010
  59. 59. trivia time! Can you guess how many function definitions there are in the Ext 3.3 framework?Monday, November 15, 2010
  60. 60. Can you guess how many function definitions there are in the Ext 3.3 framework?Monday, November 15, 2010
  61. 61. Can you guess how many function definitions there are in the Ext 3.3 framework? Is it:Monday, November 15, 2010
  62. 62. Can you guess how many function definitions there are in the Ext 3.3 framework? Is it: a: at least 2900Monday, November 15, 2010
  63. 63. Can you guess how many function definitions there are in the Ext 3.3 framework? Is it: a: at least 2900 b: at least 5300Monday, November 15, 2010
  64. 64. Can you guess how many function definitions there are in the Ext 3.3 framework? Is it: a: at least 2900 b: at least 5300 c: at least 8800Monday, November 15, 2010
  65. 65. Can you guess how many function definitions there are in the Ext 3.3 framework? Is it: a: at least 2900 b: at least 5300 c: at least 8800 d: omg! I can’t count that high !Monday, November 15, 2010
  66. 66. If you guessed: b: at least 5300...Monday, November 15, 2010
  67. 67. If you guessed: b: at least 5300...Monday, November 15, 2010
  68. 68. If you guessed: b: at least 5300... You’re Correct! but, you can’t leave early!Monday, November 15, 2010
  69. 69. Common Mistakes and BottlenecksMonday, November 15, 2010
  70. 70. Where did it go? <script type="text/javascript"> function doIt ( ) { var a = 5; say( ++a ); } setTimeout( ‘doIt();‘ , 1000); </script>Monday, November 15, 2010
  71. 71. Where did it go? <script type="text/javascript"> <script type="text/javascript"> var doIt = function ( ) { function doIt ( ) { var a = 5; var a = 5; say( ++a ); say( ++a ); } setTimeout( ‘doIt();‘ , 1000); } </script> setTimeout( ‘doIt();‘ , 1000); </script>Monday, November 15, 2010
  72. 72. Where did it go? <script type="text/javascript"> <script type="text/javascript"> var doIt = function ( ) { function doIt ( ) { var a = 5; var a = 5; say( ++a ); say( ++a ); } setTimeout( ‘doIt();‘ , 1000); } </script> setTimeout( ‘doIt();‘ , 1000); </script> create a global reference!Monday, November 15, 2010
  73. 73. Identifier Resolution Mayhem! var getAddress = function(){ return ( some.favorite.customer.we.love.name + ‘n’ + some.favorite.customer.we.love.address1 + ‘n’ + some.favorite.customer.we.love.address2 + ‘n’ + some.favorite.customer.we.love.city + ‘n’ + some.favorite.customer.we.love.state + ‘n’ + some.favorite.customer.we.love.zip ); };Monday, November 15, 2010
  74. 74. Identifier Resolution Mayhem! var getAddress = function(){ return ( some.favorite.customer.we.love.name + ‘n’ + some.favorite.customer.we.love.address1 + ‘n’ + some.favorite.customer.we.love.address2 + ‘n’ + some.favorite.customer.we.love.city + ‘n’ + some.favorite.customer.we.love.state + ‘n’ + some.favorite.customer.we.love.zip ); }; Don’t be a copy/paste victim !Monday, November 15, 2010
  75. 75. Identifier Resolution Optimized! var getAddress = function () { //resolve the global once! var cust = some.favorite.customer.we.love; return [ cust.name, cust.address1, cust.address2, cust.city, cust.state, cust.zip ].join(‘n’); };Monday, November 15, 2010
  76. 76. Iteration (with calories) Function-based Ext.each (iterable, function) Ext.iterate (iterable, function) $each $jQuery.each( iterable, function ) Enumerable.each( iterable, function ) Array.forEach(function)Monday, November 15, 2010
  77. 77. Iteration (with calories) Function-based Ext.each (iterable, function) Ext.iterate (iterable, function) $each $jQuery.each( iterable, function ) Enumerable.each( iterable, function ) Array.forEach(function) These iterators create additional scope chains. Reserve for light-duty use only!Monday, November 15, 2010
  78. 78. Traditional event binding strategiesMonday, November 15, 2010
  79. 79. Classic Quandary { xtype: ‘grid’, store : ‘storeId’, buttons : [{ text : ‘Remove Item’, handler : function(){..} , scope : ??? },{ text : ‘Close’, handler : function(){..}, scope: ??? }] }Monday, November 15, 2010
  80. 80. { xtype: ‘grid’, store : ‘storeId’, initComponent : function(){ / /template method this.buttons = [{ text : ‘Remove Item’, iconCls : ‘remove-icon’, handler : this.removeItem , scope : this },{ text : ‘Close’, handler : this.destroy, scope : this }]; this.constructor.prototype.initComponent.call(this); }, removeItem : function(button){ var record = this.getSelectionModel().getSelected(); ....... //remove the entity... } }Monday, November 15, 2010
  81. 81. Bring your desired scope into context { (without sub-classing) xtype: ‘grid’, store : ‘storeId’, initComponent : function(){ / /template method this.buttons = [{ text : ‘Remove Item’, iconCls : ‘remove-icon’, handler : this.removeItem , scope : this },{ text : ‘Close’, handler : this.destroy, scope : this }]; this.constructor.prototype.initComponent.call(this); }, removeItem : function(button){ var record = this.getSelectionModel().getSelected(); ....... //remove the entity... } }Monday, November 15, 2010
  82. 82. Poor-man’s Message Bus Revised version of Ext.util.Observable class Mechanism to loosely-couple behaviors using events (messaging) Event binding complexity reduced for most situations.Monday, November 15, 2010
  83. 83. (function(){       Ext.extend(           Ext.ux.MsgBus = function(config){                this.events = {};                Ext.apply(this,config||{});                Ext.ux.MsgBus.superclass.constructor.call(this);             },                Ext.util.Observable,          {             publish : function(topic /* ,variable arguments ,,, */  ){                  var t = String(topic);                  this.events[t] || (this.addEvents(t));                  return this.fireEvent.apply( this,  [t].concat(Array.prototype.slice.call(arguments,1)) );             }         } );        var uxp = Ext.ux.MsgBus.prototype;        Ext.apply(uxp,{           subscribe    : uxp.on,      //aliases           unsubscribe  : uxp.un,           destroy      : uxp.purgeListeners        }); })(); Follow along at: http://www.sencha.com/forum/showthread.php?42942Monday, November 15, 2010
  84. 84. Why not as a singleton? Poor candidates for Unit testing as ‘state’ is unpredictable over time, cannot be reset. Inhibits implementation flexibility. The class can be extended/overloaded further to handle custom messaging behaviors.Monday, November 15, 2010
  85. 85. Basic ux.MsgBus sample Ext.ns(your); your.bus = new Ext.ux.MsgBus(); your.bus.subscribe(test,        function(){ console.log(arguments); },       context,       {single:true, delay: 500 }     //standard Observable arguments and options     ); var wasCancelled = ( your.bus.publish( test,  this is only a test,  someObj,  someArray) === false); Monday, November 15, 2010
  86. 86. Multi-Channel Ext.namespace(your); your.bus = { channels: { // slots, topics (call it what you will) chat : new Ext.ux.MsgBus(), feeds : new Ext.ux.MsgBus(), orders : new Ext.ux.MsgBus() }, destroy : function(){ Ext.iterate(this.channels, Ext.destroy); } }; var channels = your.bus.channels; your.control = { removeItem : function(itemRecord){ var success; //handle order removal centrally here (via data.Store, Ajax, etc) success ? channels.orders.publish(‘itemremoved’, itemRecord) : channels.orders.publish(‘itemremovalfailure’, itemRecord, response); } }; channels.orders.subscribe({ remove : your.control.removeItem, ‘cancel’ : your.control.cancelOrder });      Monday, November 15, 2010
  87. 87. { xtype: ‘grid’, store : ‘storeId’, initComponent : function(){ / /template method this.buttons = [{ text : ‘Remove Item’, iconCls : ‘remove-icon’, handler : this.removeItem , scope : this },{ text : ‘Close’, handler : this.destroy, scope : this }]; this.constructor.prototype.initComponent.call(this); }, removeItem : function(button){ var record = this.getSelectionModel().getSelected(), CB = function( success) { success && button.enable(); }; channels.orders.publish(‘remove’, record, CB ); } }Monday, November 15, 2010
  88. 88. Questions ?Monday, November 15, 2010
  89. 89. Thank You! Hackathon : 4:30pm Enjoy the remainder of Senchacon 2010Monday, November 15, 2010

×