Planning JavaScript and Ajax for larger teams Christian Heilmann @media Ajax, London, November 2007
Achtung alles Lookenpeepers! Dies Machine is nicht fur gefingerpoken und mittengraben.  Is easy schnappen der springenwerk, blowenfusen und poppencorken mit spitzensparken.  Is nicht fur gewerken by das dummkopfen.  Das rubbernecken sightseeren keepen Cottenpickenen hands in das pockets - relaxen und Watch Das Blinken Lights. 
Do not fiddle with other people’s knobs unless you know what you are doing.
Spoilers: Some of the following advice will seem very basic to you. This is not based on me thinking you need this. It is meant as a reminder. Next time you encounter these problems you won’t have to think about them.  …  and Harry Potter dies, but comes back using a magic stone which is a third of the Deathly Hallows.
There is one main fatal mistake any developer can make:
There is one main fatal mistake any developer can make: Make assumptions
“ I don’t need to tell people that, they know already.”
“ Surely this has been done already, and by people better than me.”
“ This works right now, there won’t be a need to change it.”
“ This never worked in the past, it won’t work now.”
“ We hack that now, and will get time later to fix it.”
“ This is a minor issue only for this instance, no need to file a bug.”
All these mistakes are yours to make.
Sometimes they need to be made in order to prove a new point or prove an issue and its solution.
However, avoiding them means you help all of us working together.
No more heroes!
A good developer is not a very gifted and impressive developer.
It is a developer that can work with others and works for the next developer to take over.
People will move from product to product or leave the company.
Web products are never finished.
Don’t leave a mess behind; work as if you won’t see the code ever again.
Mistakes we make:
Mixing structure, presentation and behaviour. Trusting the browser. Trusting the markup. Not planning for inclusion. Not planning for failure. Premature optimization.
This should be a no-brainer by now but we still do it.
Separation means: Working in parallel (to an extend) Re-skinning an application by changing the style sheet Caching, Minimizing, Optimizing for speed and delivery.
Not separating means: Harder maintenance  Larger and slower sites  Several sources for bugs without an easy way to track them.
Mixing structure, presentation and behaviour. Trusting the browser. Trusting the markup. Not planning for inclusion. Not planning for failure. Premature optimization.
The last thing to trust is the browser.
They all have shifty eyes and will steal your loose change when you don’t look.
Testing for a browser name and assuming it can do certain things is a bad plan.
Browsers come in all kind of setups and with all kind of extensions.
Assume the browser will fail and keep poking it until it tells you all is OK.
Making assumptions: function showMessage(elm, message){ elm.firstChild.nodeValue = message; }
function showMessage(id,message){ if(document.getElementById){  var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild);  } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild);  }   } } }
function showMessage(id,message){ if(document.getElementById){  var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild);  } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild);  }   } } }
function showMessage(id,message){ if(document.getElementById){  var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild);  } }  else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild);  }   } } }
function showMessage(id,message){ if(document.getElementById){  var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; }  else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild);  } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild);  }   } } }
function showMessage(id,message){ if(document.getElementById){  var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild);  } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild);  }   } } }
function showMessage(id,message){ if(document.getElementById){  var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; }  else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild);  } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild);  }   } } }
function showMessage(id,message){ if(document.getElementById){  var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild);   } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild);  }   } } }
function showMessage(id,message){ if(document.getElementById){  var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild);  } }  else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild);  }   } } }
function showMessage(id,message){ if(document.getElementById){  var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild);  } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild);   }   } } }
function showMessage(id,message){ if(document.getElementById){  var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild);  } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild);  }   } } }
Bit overkill, isn’t it?
Add tests for the browser early (init method) Use library functions that do the testing for you.
Mixing structure, presentation and behaviour. Trusting the browser. Trusting   the markup. Not planning for inclusion. Not planning for failure. Premature optimization.
HTML markup of the document is never set in stone.
Don’t rely on it.
document.getElementById('nav').getElementsByTagName('li')[3].firstChild.getElmentsByTagName('span')[2].nodeValue = 'offline';
document.getElementById('nav').getElementsByTagName('li')[3].firstChild.getElmentsByTagName('span')[2].nodeValue = 'offline';
Mixing structure, presentation and behaviour. Trusting the browser. Trusting the markup. Not planning for inclusion. Not planning for failure. Premature optimization.
Assuming your script is the only one included in the document:
Assuming your script is the only one included in the document: hasfail = true;
Namespace your scripts, follow a naming convention and don’t leave any global variables or methods.
That way your script will run even if it has to work alongside bad code.
Bad code will be added to your documents, most of the time in the form of advertisements or tracking code.
Mixing structure, presentation and behaviour. Trusting the browser. Trusting the markup. Not planning for inclusion. Not planning for failure. Premature optimization.
Things will fail, plan for it! JavaScript will not be available. Ajax connections will take too long or return wrong data.  Plan for a fallback option (redirect to a static page, show an error message)
<a href=&quot;javascript:ajaxmagic('panda')&quot;> Show results for 'panda' </a>
<a href=&quot;javascript:ajaxmagic('panda')&quot;> Show results for 'panda' </a>
<a href=&quot;search.php?term=panda&quot; id=&quot;searchlink&quot;> Show results for 'panda‘ </a> var YE = YAHOO.util.Event; YE.on('searchlink','click',ajaxmagic); function ajaxmagic(e){ var t = YE.getTarget(e); var url = t.href.split('=')[1]; ajaxcode(url); YE.preventDefault(e); }
Re-use the backend script function ajaxmagic(e){ var t = YE.getTarget(e); var url = t.href + &output=json'; ajaxcode(url); YE.preventDefault(e); }
Mixing structure, presentation and behaviour. Trusting the browser. Trusting the markup. Not planning for inclusion. Not planning for failure. Premature   optimization .
Each of us has a little hacker inside who wants to get out.
This little hacker wants to make things as fast, small and cool as possible.
This little hacker is also very competitive and doesn’t trust reused code or libraries.
 
Our job is not to give in to it when we produce production code.
Production code does not need to be optimized from the start.
It needs to be understandable and maintainable.
use library code, even if it appears huge (a lot of the size is a myth) Use comments to explain what is going on Use explanatory variable and method names Don’t reinvent the wheel even if you consider yours superior.
Enough bad. Give us some tips!
Follow a diet plan. Have a build process. Have a code standard and documentation process. Review and reuse code. Plan for extension. Think maintenance
Try to avoid traps that make your code hungry: Cut down on DOM interaction  Minimize the amount of loops  Build tool methods to deal with reoccurring problems
Use shortcut notations in JavaScript.
var links = new Array(); links[0]='http://icant.co.uk'; links[1]='http://wait-till-i.com'; links[2]='http://onlinetools.org';
var links = new Array(); links[0]='http://icant.co.uk'; links[1]='http://wait-till-i.com'; links[2]='http://onlinetools.org'; var links = [ 'http://icant.co.uk', 'http://wait-till-i.com', 'http://onlinetools.org‘ ];
var contact = new Object(); contact.name = 'Christian'; contact.surName = 'Heilmann'; contact.age = 32; contact.hair = 'slightly red';
var contact = new Object(); contact.name = 'Christian'; contact.surName = 'Heilmann'; contact.age = 32; contact.hair = 'slightly red'; var contact = { name:'Christian', surName:'Heilmann', age:32, hair:'slightly red' };
if(hasCheeseburger){ cat.mood = 'happy'; } else { cat.mood = 'sad'; }
if(hasCheeseburger){ cat.mood = 'happy'; } else { cat.mood = 'sad'; } cat.mood = hasCheeseburger?'happy':'sad';
if(hasCheeseburger){ cat.mood = 'happy'; } else { cat.mood = 'sad'; } cat.mood = hasCheeseburger?'happy':'sad'; condition
if(hasCheeseburger){ cat.mood = 'happy'; } else { cat.mood = 'sad'; } cat.mood = hasCheeseburger?'happy':'sad'; true case
if(hasCheeseburger){ cat.mood = 'happy'; } else { cat.mood = 'sad'; } cat.mood = hasCheeseburger?'happy':'sad'; false case
if(obj.getClass()===' full '){ var x = screen.left; } else { var x = current; }
if(obj.getClass()===' full '){ var x = screen.left; } else { var x = current; } var x = (obj.hasClass()=== ' full ')  ? screen.left : current;
var cat; if(canHasCheeseburger){ cat = canHasCheeseburger; };  if(garfield){ cat = garfield; };
var cat; if(canHasCheeseburger){ cat = canHasCheeseburger; };  if(garfield){ cat = garfield; }; var cat = canHasCheeseburger || garfield;
var cat; if(canHasCheeseburger){ cat = canHasCheeseburger; };  if(garfield){ cat = garfield; }; var cat = canHasCheeseburger || garfield; one or the other, defining a fallback
var massive.name.with.long.namespace = { ...private stuff... return{ init:function(){ massive.name.with.long.namespace.show(); }, show:function(){ massive.name.with.long.namespace.test(); }, test:function(){ } } }();
var massive.name.with.long.namespace = { var pub = {}; ...private stuff... pub. init = function(){ pub. show(); }; pub. show = function(){ pub. test(); }; pub. test = function(){ }; return pub; }(); massive.name.with.long.namespace.init();
var massive.name.with.long.namespace = { function init(){ show(); }; function show(){ test(); }; function test(){ }; return { init:init; show:show; test:test; }; }(); massive.name.with.long.namespace.init();
Follow a diet plan. Have a build process. Have a code standard and documentation process. Review and reuse code. Plan for extension. Think maintenance
Production code is not live code.  That doesn’t happen on the back-end and it shouldn’t happen on the front-end. Live code is there for machines, production code is there for humans.
Build process: Validation (Tidy, JSLint) Minification (JSMin, CSS minifier) Consolidation (one CSS and one JS instead of dozens) Tagging as “live code” – do not edit!
Follow a diet plan. Have a build process. Have a code standard and documentation process. Review and reuse code. Plan for extension. Think maintenance
Following a code standard means you can: Assess quality of code  Find bugs easily and create reproducible bug reports Have quick handover from developer to developer Have reliable version control
What code standard?
Whatever the team agrees on and feels comfortable with.
Document it and other teams can validate what you have done.
In the perfect world, we’ll all follow the same code standard.
Let’s meet again in a year! :-)
Comments are good, but they are not documentation.
Write documentation in peer review - as the developer you are too close to the subject.
Plan and ask for time to document what you have done.
Follow a diet plan. Have a build process. Have a code standard and documentation process. Review and reuse code. Plan for extension. Think maintenance
Conduct Code reviews You find problems and solutions you can share in the team. You find out who knows what well and who needs training in what You share the knowledge throughout the team = no Divas.
If you keep finding the same problem and different solutions for it, find a generic solution and re-use that one. Look at what other people have done (libraries). Bounce your solutions off other development teams.
Follow a diet plan. Have a build process. Have a code standard and documentation process. Review and reuse your code. Plan for extension. Think maintenance
Whenever you write some code, don’t think that your implementation will be the end of it.
Make sure that your code can be extended by other people and try to build it as modular as possible.
Follow a diet plan. Have a build process. Have a code standard and documentation process. Review and reuse your code. Plan for extension. Think maintenance
Not everybody maintaining your code will be as good as you are.
Trying to find where to change what in a piece of code is terribly frustrating.
Separate out as much of the look and feel as you can.
Also separate out labels that are likely to change and the names of CSS classes and IDs in use.
So how do you plan JavaScript and Ajax for larger teams?
Get the team to talk and agree on what works best.
Involve Design and Engineering in the process and explain the rationale of your plan.
Communication and sharing information is better than any architectural blueprint you or I could come up with.
THANKS! Christian  Heilmann http://wait-till-i.com [email_address]

Planning JavaScript for Larger Teams - Draft & Handout version

  • 1.
    Planning JavaScript andAjax for larger teams Christian Heilmann @media Ajax, London, November 2007
  • 2.
    Achtung alles Lookenpeepers!Dies Machine is nicht fur gefingerpoken und mittengraben. Is easy schnappen der springenwerk, blowenfusen und poppencorken mit spitzensparken. Is nicht fur gewerken by das dummkopfen. Das rubbernecken sightseeren keepen Cottenpickenen hands in das pockets - relaxen und Watch Das Blinken Lights. 
  • 3.
    Do not fiddlewith other people’s knobs unless you know what you are doing.
  • 4.
    Spoilers: Some ofthe following advice will seem very basic to you. This is not based on me thinking you need this. It is meant as a reminder. Next time you encounter these problems you won’t have to think about them. … and Harry Potter dies, but comes back using a magic stone which is a third of the Deathly Hallows.
  • 5.
    There is onemain fatal mistake any developer can make:
  • 6.
    There is onemain fatal mistake any developer can make: Make assumptions
  • 7.
    “ I don’tneed to tell people that, they know already.”
  • 8.
    “ Surely thishas been done already, and by people better than me.”
  • 9.
    “ This worksright now, there won’t be a need to change it.”
  • 10.
    “ This neverworked in the past, it won’t work now.”
  • 11.
    “ We hackthat now, and will get time later to fix it.”
  • 12.
    “ This isa minor issue only for this instance, no need to file a bug.”
  • 13.
    All these mistakesare yours to make.
  • 14.
    Sometimes they needto be made in order to prove a new point or prove an issue and its solution.
  • 15.
    However, avoiding themmeans you help all of us working together.
  • 16.
  • 17.
    A good developeris not a very gifted and impressive developer.
  • 18.
    It is adeveloper that can work with others and works for the next developer to take over.
  • 19.
    People will movefrom product to product or leave the company.
  • 20.
    Web products arenever finished.
  • 21.
    Don’t leave amess behind; work as if you won’t see the code ever again.
  • 22.
  • 23.
    Mixing structure, presentationand behaviour. Trusting the browser. Trusting the markup. Not planning for inclusion. Not planning for failure. Premature optimization.
  • 24.
    This should bea no-brainer by now but we still do it.
  • 25.
    Separation means: Workingin parallel (to an extend) Re-skinning an application by changing the style sheet Caching, Minimizing, Optimizing for speed and delivery.
  • 26.
    Not separating means:Harder maintenance Larger and slower sites Several sources for bugs without an easy way to track them.
  • 27.
    Mixing structure, presentationand behaviour. Trusting the browser. Trusting the markup. Not planning for inclusion. Not planning for failure. Premature optimization.
  • 28.
    The last thingto trust is the browser.
  • 29.
    They all haveshifty eyes and will steal your loose change when you don’t look.
  • 30.
    Testing for abrowser name and assuming it can do certain things is a bad plan.
  • 31.
    Browsers come inall kind of setups and with all kind of extensions.
  • 32.
    Assume the browserwill fail and keep poking it until it tells you all is OK.
  • 33.
    Making assumptions: functionshowMessage(elm, message){ elm.firstChild.nodeValue = message; }
  • 34.
    function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } } }
  • 35.
    function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } } }
  • 36.
    function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } } }
  • 37.
    function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } } }
  • 38.
    function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } } }
  • 39.
    function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } } }
  • 40.
    function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } } }
  • 41.
    function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } } }
  • 42.
    function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } } }
  • 43.
    function showMessage(id,message){ if(document.getElementById){ var elm = document.getElementById(id); if(elm){ if(elm.firstChild){ if(elm.firstChild.nodeType === 3){ elm.firstChild.nodeValue = message; } else { var t = document.createTextNode(message); elm.insertBefore(t,elm.firstChild); } } else { var t = document.createTextNode(message); elm.appendChild(t,elm.firstChild); } } } }
  • 44.
  • 45.
    Add tests forthe browser early (init method) Use library functions that do the testing for you.
  • 46.
    Mixing structure, presentationand behaviour. Trusting the browser. Trusting the markup. Not planning for inclusion. Not planning for failure. Premature optimization.
  • 47.
    HTML markup ofthe document is never set in stone.
  • 48.
  • 49.
  • 50.
  • 51.
    Mixing structure, presentationand behaviour. Trusting the browser. Trusting the markup. Not planning for inclusion. Not planning for failure. Premature optimization.
  • 52.
    Assuming your scriptis the only one included in the document:
  • 53.
    Assuming your scriptis the only one included in the document: hasfail = true;
  • 54.
    Namespace your scripts,follow a naming convention and don’t leave any global variables or methods.
  • 55.
    That way yourscript will run even if it has to work alongside bad code.
  • 56.
    Bad code willbe added to your documents, most of the time in the form of advertisements or tracking code.
  • 57.
    Mixing structure, presentationand behaviour. Trusting the browser. Trusting the markup. Not planning for inclusion. Not planning for failure. Premature optimization.
  • 58.
    Things will fail,plan for it! JavaScript will not be available. Ajax connections will take too long or return wrong data. Plan for a fallback option (redirect to a static page, show an error message)
  • 59.
  • 60.
  • 61.
    <a href=&quot;search.php?term=panda&quot; id=&quot;searchlink&quot;>Show results for 'panda‘ </a> var YE = YAHOO.util.Event; YE.on('searchlink','click',ajaxmagic); function ajaxmagic(e){ var t = YE.getTarget(e); var url = t.href.split('=')[1]; ajaxcode(url); YE.preventDefault(e); }
  • 62.
    Re-use the backendscript function ajaxmagic(e){ var t = YE.getTarget(e); var url = t.href + &output=json'; ajaxcode(url); YE.preventDefault(e); }
  • 63.
    Mixing structure, presentationand behaviour. Trusting the browser. Trusting the markup. Not planning for inclusion. Not planning for failure. Premature optimization .
  • 64.
    Each of ushas a little hacker inside who wants to get out.
  • 65.
    This little hackerwants to make things as fast, small and cool as possible.
  • 66.
    This little hackeris also very competitive and doesn’t trust reused code or libraries.
  • 67.
  • 68.
    Our job isnot to give in to it when we produce production code.
  • 69.
    Production code doesnot need to be optimized from the start.
  • 70.
    It needs tobe understandable and maintainable.
  • 71.
    use library code,even if it appears huge (a lot of the size is a myth) Use comments to explain what is going on Use explanatory variable and method names Don’t reinvent the wheel even if you consider yours superior.
  • 72.
    Enough bad. Giveus some tips!
  • 73.
    Follow a dietplan. Have a build process. Have a code standard and documentation process. Review and reuse code. Plan for extension. Think maintenance
  • 74.
    Try to avoidtraps that make your code hungry: Cut down on DOM interaction Minimize the amount of loops Build tool methods to deal with reoccurring problems
  • 75.
    Use shortcut notationsin JavaScript.
  • 76.
    var links =new Array(); links[0]='http://icant.co.uk'; links[1]='http://wait-till-i.com'; links[2]='http://onlinetools.org';
  • 77.
    var links =new Array(); links[0]='http://icant.co.uk'; links[1]='http://wait-till-i.com'; links[2]='http://onlinetools.org'; var links = [ 'http://icant.co.uk', 'http://wait-till-i.com', 'http://onlinetools.org‘ ];
  • 78.
    var contact =new Object(); contact.name = 'Christian'; contact.surName = 'Heilmann'; contact.age = 32; contact.hair = 'slightly red';
  • 79.
    var contact =new Object(); contact.name = 'Christian'; contact.surName = 'Heilmann'; contact.age = 32; contact.hair = 'slightly red'; var contact = { name:'Christian', surName:'Heilmann', age:32, hair:'slightly red' };
  • 80.
    if(hasCheeseburger){ cat.mood ='happy'; } else { cat.mood = 'sad'; }
  • 81.
    if(hasCheeseburger){ cat.mood ='happy'; } else { cat.mood = 'sad'; } cat.mood = hasCheeseburger?'happy':'sad';
  • 82.
    if(hasCheeseburger){ cat.mood ='happy'; } else { cat.mood = 'sad'; } cat.mood = hasCheeseburger?'happy':'sad'; condition
  • 83.
    if(hasCheeseburger){ cat.mood ='happy'; } else { cat.mood = 'sad'; } cat.mood = hasCheeseburger?'happy':'sad'; true case
  • 84.
    if(hasCheeseburger){ cat.mood ='happy'; } else { cat.mood = 'sad'; } cat.mood = hasCheeseburger?'happy':'sad'; false case
  • 85.
    if(obj.getClass()===' full '){var x = screen.left; } else { var x = current; }
  • 86.
    if(obj.getClass()===' full '){var x = screen.left; } else { var x = current; } var x = (obj.hasClass()=== ' full ') ? screen.left : current;
  • 87.
    var cat; if(canHasCheeseburger){cat = canHasCheeseburger; }; if(garfield){ cat = garfield; };
  • 88.
    var cat; if(canHasCheeseburger){cat = canHasCheeseburger; }; if(garfield){ cat = garfield; }; var cat = canHasCheeseburger || garfield;
  • 89.
    var cat; if(canHasCheeseburger){cat = canHasCheeseburger; }; if(garfield){ cat = garfield; }; var cat = canHasCheeseburger || garfield; one or the other, defining a fallback
  • 90.
    var massive.name.with.long.namespace ={ ...private stuff... return{ init:function(){ massive.name.with.long.namespace.show(); }, show:function(){ massive.name.with.long.namespace.test(); }, test:function(){ } } }();
  • 91.
    var massive.name.with.long.namespace ={ var pub = {}; ...private stuff... pub. init = function(){ pub. show(); }; pub. show = function(){ pub. test(); }; pub. test = function(){ }; return pub; }(); massive.name.with.long.namespace.init();
  • 92.
    var massive.name.with.long.namespace ={ function init(){ show(); }; function show(){ test(); }; function test(){ }; return { init:init; show:show; test:test; }; }(); massive.name.with.long.namespace.init();
  • 93.
    Follow a dietplan. Have a build process. Have a code standard and documentation process. Review and reuse code. Plan for extension. Think maintenance
  • 94.
    Production code isnot live code. That doesn’t happen on the back-end and it shouldn’t happen on the front-end. Live code is there for machines, production code is there for humans.
  • 95.
    Build process: Validation(Tidy, JSLint) Minification (JSMin, CSS minifier) Consolidation (one CSS and one JS instead of dozens) Tagging as “live code” – do not edit!
  • 96.
    Follow a dietplan. Have a build process. Have a code standard and documentation process. Review and reuse code. Plan for extension. Think maintenance
  • 97.
    Following a codestandard means you can: Assess quality of code Find bugs easily and create reproducible bug reports Have quick handover from developer to developer Have reliable version control
  • 98.
  • 99.
    Whatever the teamagrees on and feels comfortable with.
  • 100.
    Document it andother teams can validate what you have done.
  • 101.
    In the perfectworld, we’ll all follow the same code standard.
  • 102.
    Let’s meet againin a year! :-)
  • 103.
    Comments are good,but they are not documentation.
  • 104.
    Write documentation inpeer review - as the developer you are too close to the subject.
  • 105.
    Plan and askfor time to document what you have done.
  • 106.
    Follow a dietplan. Have a build process. Have a code standard and documentation process. Review and reuse code. Plan for extension. Think maintenance
  • 107.
    Conduct Code reviewsYou find problems and solutions you can share in the team. You find out who knows what well and who needs training in what You share the knowledge throughout the team = no Divas.
  • 108.
    If you keepfinding the same problem and different solutions for it, find a generic solution and re-use that one. Look at what other people have done (libraries). Bounce your solutions off other development teams.
  • 109.
    Follow a dietplan. Have a build process. Have a code standard and documentation process. Review and reuse your code. Plan for extension. Think maintenance
  • 110.
    Whenever you writesome code, don’t think that your implementation will be the end of it.
  • 111.
    Make sure thatyour code can be extended by other people and try to build it as modular as possible.
  • 112.
    Follow a dietplan. Have a build process. Have a code standard and documentation process. Review and reuse your code. Plan for extension. Think maintenance
  • 113.
    Not everybody maintainingyour code will be as good as you are.
  • 114.
    Trying to findwhere to change what in a piece of code is terribly frustrating.
  • 115.
    Separate out asmuch of the look and feel as you can.
  • 116.
    Also separate outlabels that are likely to change and the names of CSS classes and IDs in use.
  • 117.
    So how doyou plan JavaScript and Ajax for larger teams?
  • 118.
    Get the teamto talk and agree on what works best.
  • 119.
    Involve Design andEngineering in the process and explain the rationale of your plan.
  • 120.
    Communication and sharinginformation is better than any architectural blueprint you or I could come up with.
  • 121.
    THANKS! Christian Heilmann http://wait-till-i.com [email_address]