javascript: advanced scoping & other puzzles
DESCRIPTION
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."TRANSCRIPT
![Page 1: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/1.jpg)
Monday, November 15, 2010
![Page 2: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/2.jpg)
Doug Hendricks
Solutions ArchitectSencha Services
Monday, November 15, 2010
![Page 3: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/3.jpg)
ECMAScope Soup
‘From the can’, alternate recipes,
and puzzles.
Monday, November 15, 2010
![Page 4: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/4.jpg)
• 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 Components
On the menu:
Monday, November 15, 2010
![Page 5: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/5.jpg)
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>
Global Variables
Monday, November 15, 2010
![Page 6: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/6.jpg)
What is the global object(namespace)?
Browsers, GreaseMonkey : window
HTML5 Workers, Node.Js : global
Monday, November 15, 2010
![Page 7: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/7.jpg)
<script type="text/javascript"> globalB = 4;
var globalA = 3, say = console.log;</script>
or, referenced through the global object as:window.globalAwindow.say
Global Variables
Monday, November 15, 2010
![Page 8: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/8.jpg)
Local variables - survive only as long as the Function block they are declared in has an execution context.
Local Variables
<script type="text/javascript"> var globalA, say = console.log;
function doIt ( ) { var localA = 5; //local scope only } </script>
Monday, November 15, 2010
![Page 9: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/9.jpg)
<script type="text/javascript"> var globalA, say = console.log,
a = 4; doIt(); function doIt ( ) {
say ( a ); var a = 5; say( ++a ); } </script>
Something wrong here?
Monday, November 15, 2010
![Page 10: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/10.jpg)
<script type="text/javascript"> var globalA, say = console.log,
a = 4; doIt(); function doIt ( ) {
say ( a ); var a = 5; say( ++a ); } </script>
Something wrong here?
Monday, November 15, 2010
![Page 11: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/11.jpg)
<script type="text/javascript"> var globalA, say = console.log,
a = 4; doIt(); function doIt ( ) {
say ( a ); var a = 5; say( ++a ); } </script>
Something wrong here?
<- this can’t work!
<- this is 4, right?
Monday, November 15, 2010
![Page 12: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/12.jpg)
<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
![Page 13: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/13.jpg)
introducing...
activation objects,scope chain,
identifier resolution
Monday, November 15, 2010
![Page 14: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/14.jpg)
Execution context initialized containing a ‘root’ or global object.
Monday, November 15, 2010
![Page 15: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/15.jpg)
Execution context initialized containing a ‘root’ or global object.
<script type="text/javascript"> var globalA, say = console.log, a = 4; doIt(); function doIt ( ) {
say ( a ); var a = 5; say( ++a ); } </script>
global
window : objectdocument : objectnavigator : object
a : 4doIt : function
globalA : undefinedsay : function
Scope chain
Monday, November 15, 2010
![Page 16: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/16.jpg)
next, an activation object is prepended to the scope-chain by first scanning the function body for local var’s:
globalwindow : object
document : objectnavigator : object
a : 4doIt : function
globalA : undefined
Monday, November 15, 2010
![Page 17: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/17.jpg)
next, an activation object is prepended to the scope-chain by first scanning the function body for local var’s:
doIt(); function doIt ( ) {
say ( a ); var a = 5; say( ++a ); }
activationarguments : []this : windowa : undefined
Scope chain
thus, a new context is created for doIt, containing a local ‘a’
globalwindow : object
document : objectnavigator : object
a : 4doIt : function
globalA : undefined
Monday, November 15, 2010
![Page 18: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/18.jpg)
Identifier resolution: get me ‘say’ ! (the hunt begins)
function doIt ( ) {
say ( a ); var a = 5; say( ++a ); }
globalwindow : object
document : objectnavigator : object
a : 4say : function
activationarguments : []this : windowa : undefined
Scope chain
Monday, November 15, 2010
![Page 19: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/19.jpg)
Identifier resolution: get me ‘say’ ! (the hunt begins)
function doIt ( ) {
say ( a ); var a = 5; say( ++a ); }
globalwindow : object
document : objectnavigator : object
a : 4say : function
activationarguments : []this : windowa : undefined
Scope chain
local?, nope!
Monday, November 15, 2010
![Page 20: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/20.jpg)
Identifier resolution: get me ‘say’ ! (the hunt begins)
function doIt ( ) {
say ( a ); var a = 5; say( ++a ); }
globalwindow : object
document : objectnavigator : object
a : 4say : function
activationarguments : []this : windowa : undefined
Scope chain
local?, nope!
global has it!
Monday, November 15, 2010
![Page 21: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/21.jpg)
Now, on to the function argument: ‘a’
function doIt ( ) {
say ( a ); var a = 5; say( ++a ); } global
window : objectdocument : objectnavigator : object
a : 4 say : function
activationarguments : []this : windowa : undefined
Scope chain
Monday, November 15, 2010
![Page 22: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/22.jpg)
Now, on to the function argument: ‘a’
function doIt ( ) {
say ( a ); var a = 5; say( ++a ); } global
window : objectdocument : objectnavigator : object
a : 4 say : function
activationarguments : []this : windowa : undefined
Scope chain
<- prints: undefined<- NOT 5!
Monday, November 15, 2010
![Page 23: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/23.jpg)
Now, on to assignment...
function doIt ( ) {
say ( a ); var a = 5; say( ++a ); }
globalwindow : object
document : objectnavigator : object
a : 4 say : function
activationarguments : []this : windowa : undefined
Scope chain
Monday, November 15, 2010
![Page 24: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/24.jpg)
Now, on to assignment...
function doIt ( ) {
say ( a ); var a = 5; say( ++a ); }
globalwindow : object
document : objectnavigator : object
a : 4 say : function
activationarguments : []this : windowa : undefined
Scope chain
local? yes, set it!
and so on...
activationarguments : []this : window
a : 5
Monday, November 15, 2010
![Page 25: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/25.jpg)
When function doIt is completed, it’s execution context (scope chain) is destroyed:
doIt(); function doIt ( ) {
say ( a ); var a = 5; say( ++a ); }
globalwindow : object
document : objectnavigator : object
a : 4 say : function
activationarguments : []this : window
a : 5
Scope chain
Monday, November 15, 2010
![Page 26: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/26.jpg)
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
![Page 27: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/27.jpg)
Monday, November 15, 2010
![Page 28: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/28.jpg)
Extra fat ?(Scope Chain Augmentation)
Monday, November 15, 2010
![Page 29: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/29.jpg)
(Scope Chain Augmentation)
Monday, November 15, 2010
![Page 30: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/30.jpg)
Scope Chain Augmentation
The big offenders:
Monday, November 15, 2010
![Page 31: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/31.jpg)
Scope Chain Augmentation
Closures
with Clause
catch clause of try/catch
The big offenders:
Monday, November 15, 2010
![Page 32: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/32.jpg)
Scope Chain AugmentationFunction Closures
var trimString = function () { var reReplace = /^\s+|\s+$/g;
return ( function (str){ return str.replace(reReplace, ‘’);
} );}( ); <- create the closure
globalwindow : object
document : objectnavigator : object
Monday, November 15, 2010
![Page 33: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/33.jpg)
Scope Chain AugmentationFunction Closures
var trimString = function () { var reReplace = /^\s+|\s+$/g;
return ( function (str){ return str.replace(reReplace, ‘’);
} );}( ); <- create the closure
activationarguments : []this : window
reReplace : RegExp
globalwindow : object
document : objectnavigator : object
activationarguments : [str]this : window
Monday, November 15, 2010
![Page 34: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/34.jpg)
Scope Chain AugmentationFunction Closures
var trimString = function () { var reReplace = /^\s+|\s+$/g;
return ( function (str){ return str.replace(reReplace, ‘’);
} );}( ); <- create the closure
activationarguments : []this : window
reReplace : RegExp
globalwindow : object
document : objectnavigator : object
activationarguments : [str]this : window
Closures will always have 3 scope chain members,
minimum!Monday, November 15, 2010
![Page 35: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/35.jpg)
Scope Chain AugmentationFunction 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 });}
globalwindow : object
document : objectnavigator : object
Monday, November 15, 2010
![Page 36: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/36.jpg)
Scope Chain AugmentationFunction 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 });}
activationarguments : []this : window
els : Ext.CompositeEl...doc : Ext.Element
globalwindow : object
document : objectnavigator : object
activationarguments : [e, target]
this : Ext.Element
Monday, November 15, 2010
![Page 37: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/37.jpg)
Monday, November 15, 2010
![Page 38: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/38.jpg)
Even more fat !?(with Clause)
Monday, November 15, 2010
![Page 39: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/39.jpg)
Monday, November 15, 2010
![Page 40: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/40.jpg)
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
![Page 41: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/41.jpg)
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 });}
activationarguments : []
globalwindow : object
activationarguments : [e, target]
Monday, November 15, 2010
![Page 42: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/42.jpg)
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 });}
activationarguments : []
globalwindow : object
activationarguments : [e, target]
variableels : Ext.CompositeEl...
Monday, November 15, 2010
![Page 43: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/43.jpg)
Monday, November 15, 2010
![Page 44: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/44.jpg)
Let’s just eat Lard !(catch in try/catch)
Monday, November 15, 2010
![Page 45: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/45.jpg)
Monday, November 15, 2010
![Page 46: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/46.jpg)
Scope Chain Augmentationcatch block
doc.on({ 'click' : function(e, target){
try{ with (els) {
removeClass(‘puff’); highlight();
}
} catch( err ) { Ext.MessageBox.alert(‘Ooops’);}
},
Monday, November 15, 2010
![Page 47: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/47.jpg)
Scope Chain Augmentationcatch block
doc.on({ 'click' : function(e, target){
try{ with (els) {
removeClass(‘puff’); highlight();
}
} catch( err ) { Ext.MessageBox.alert(‘Ooops’);}
},
activationarguments : []
globalwindow : object
activationarguments : [e, target]
Monday, November 15, 2010
![Page 48: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/48.jpg)
Scope Chain Augmentationcatch block
doc.on({ 'click' : function(e, target){
try{ with (els) {
removeClass(‘puff’); highlight();
}
} catch( err ) { Ext.MessageBox.alert(‘Ooops’);}
},
activationarguments : []
globalwindow : object
activationarguments : [e, target]
variablearguments : [err]
Monday, November 15, 2010
![Page 49: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/49.jpg)
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
![Page 50: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/50.jpg)
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 });}
Expensive
Monday, November 15, 2010
![Page 51: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/51.jpg)
Optimizations
function puffEmUp () {
var E = Ext, els = E.select('div');
els.addClass('puff');
E.getDoc().on({ 'click' : function(e, target){
var collect = els;collect.removeClass(‘puff’);
collect.highlight(); }, ‘delegate’ : 'div.puff', ‘single’ : true });}
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 });}
Expensive Better
Monday, November 15, 2010
![Page 52: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/52.jpg)
Optimize Furtherfunction 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 });}
function puffEmUp () {
var E = Ext, els = E.select('div');
els.addClass('puff');
E.getDoc().on({ 'click' : function(e, target){
var collect = els;collect.removeClass(‘puff’);
collect.highlight(); }, ‘delegate’ : 'div.puff', ‘single’ : true });}
Monday, November 15, 2010
![Page 53: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/53.jpg)
Optimize Furtherfunction 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 });}
Betterfunction puffEmUp () {
var E = Ext, els = E.select('div');
els.addClass('puff');
E.getDoc().on({ 'click' : function(e, target){
var collect = els;collect.removeClass(‘puff’);
collect.highlight(); }, ‘delegate’ : 'div.puff', ‘single’ : true });}
Monday, November 15, 2010
![Page 54: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/54.jpg)
Leverage Execution Contextfunction 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
![Page 55: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/55.jpg)
Leverage Execution Contextfunction 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 });}
Replace scope-chain traversal with a single context (this)
prototype search.
Monday, November 15, 2010
![Page 56: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/56.jpg)
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
![Page 57: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/57.jpg)
Why is this important at all?
Monday, November 15, 2010
![Page 58: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/58.jpg)
trivia time!
Monday, November 15, 2010
![Page 59: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/59.jpg)
Can you guess how manyfunction definitions there are in the
Ext 3.3 framework?
trivia time!
Monday, November 15, 2010
![Page 60: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/60.jpg)
Can you guess how manyfunction definitions there are in the
Ext 3.3 framework?
Monday, November 15, 2010
![Page 61: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/61.jpg)
Can you guess how manyfunction definitions there are in the
Ext 3.3 framework?
Is it:
Monday, November 15, 2010
![Page 62: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/62.jpg)
Can you guess how manyfunction definitions there are in the
Ext 3.3 framework?
Is it:
a: at least 2900
Monday, November 15, 2010
![Page 63: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/63.jpg)
Can you guess how manyfunction definitions there are in the
Ext 3.3 framework?
Is it:
a: at least 2900b: at least 5300
Monday, November 15, 2010
![Page 64: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/64.jpg)
Can you guess how manyfunction definitions there are in the
Ext 3.3 framework?
Is it:
a: at least 2900b: at least 5300c: at least 8800
Monday, November 15, 2010
![Page 65: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/65.jpg)
Can you guess how manyfunction definitions there are in the
Ext 3.3 framework?
Is it:
a: at least 2900b: at least 5300c: at least 8800d: omg! I can’t count that high !
Monday, November 15, 2010
![Page 66: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/66.jpg)
If you guessed:
b: at least 5300...
Monday, November 15, 2010
![Page 67: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/67.jpg)
If you guessed:
b: at least 5300...
Monday, November 15, 2010
![Page 68: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/68.jpg)
If you guessed:
b: at least 5300...
You’re Correct! but, you can’t leave early!
Monday, November 15, 2010
![Page 69: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/69.jpg)
Common Mistakes and Bottlenecks
Monday, November 15, 2010
![Page 70: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/70.jpg)
Where did it go?
<script type="text/javascript">
function doIt ( ) { var a = 5; say( ++a ); }
setTimeout( ‘doIt();‘ , 1000);
</script>
Monday, November 15, 2010
![Page 71: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/71.jpg)
Where did it go?
<script type="text/javascript"> function doIt ( ) { var a = 5; say( ++a ); } setTimeout( ‘doIt();‘ , 1000); </script>
<script type="text/javascript"> var doIt = function ( ) { var a = 5; say( ++a ); }
setTimeout( ‘doIt();‘ , 1000); </script>
Monday, November 15, 2010
![Page 72: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/72.jpg)
Where did it go?
<script type="text/javascript"> function doIt ( ) { var a = 5; say( ++a ); } setTimeout( ‘doIt();‘ , 1000); </script>
<script type="text/javascript"> var doIt = function ( ) { var a = 5; say( ++a ); }
setTimeout( ‘doIt();‘ , 1000); </script>
create a global reference!
Monday, November 15, 2010
![Page 73: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/73.jpg)
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
![Page 74: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/74.jpg)
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
![Page 75: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/75.jpg)
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
![Page 76: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/76.jpg)
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
![Page 77: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/77.jpg)
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
![Page 78: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/78.jpg)
Traditional event binding strategies
Monday, November 15, 2010
![Page 79: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/79.jpg)
{xtype: ‘grid’,store : ‘storeId’,buttons : [{ text : ‘Remove Item’, handler : function(){..} , scope : ??? },{ text : ‘Close’, handler : function(){..}, scope: ??? }]}
Classic Quandary
Monday, November 15, 2010
![Page 80: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/80.jpg)
{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
![Page 81: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/81.jpg)
{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... }}
Bring your desired scope into context(without sub-classing)
Monday, November 15, 2010
![Page 82: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/82.jpg)
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
![Page 83: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/83.jpg)
(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?42942
Monday, November 15, 2010
![Page 84: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/84.jpg)
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
![Page 85: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/85.jpg)
Basic ux.MsgBus sampleExt.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
![Page 86: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/86.jpg)
Multi-ChannelExt.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
![Page 87: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/87.jpg)
{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
![Page 88: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/88.jpg)
Questions ?
Monday, November 15, 2010
![Page 89: JavaScript: Advanced Scoping & Other Puzzles](https://reader038.vdocuments.mx/reader038/viewer/2022102705/54696e25af7959c32b8b4a81/html5/thumbnails/89.jpg)
Thank You!
Hackathon : 4:30pm
Enjoy the remainder of Senchacon 2010
Monday, November 15, 2010