Your SlideShare is downloading. ×
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Maintainable JavaScript 2011
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Maintainable JavaScript 2011

15,134

Published on

Writing JavaScript as a hobby and writing JavaScript as a job are two very different things. Learn some common practices for making your JavaScript friendly to a team environment.

Writing JavaScript as a hobby and writing JavaScript as a job are two very different things. Learn some common practices for making your JavaScript friendly to a team environment.

Published in: Technology
0 Comments
70 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
15,134
On Slideshare
0
From Embeds
0
Number of Embeds
13
Actions
Shares
0
Downloads
320
Comments
0
Likes
70
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. flickr.com/photos/jontysewell/4526861658/ Maintainable JavaScript Nicholas C. Zakas | @slicknet
  • 2. Whos this guy? 5 years Co-Creator Contributor,Tech Lead, Yahoo! csslint.net Creator of YUI Test Author Lead Author Contributor Lead Author
  • 3. MaintainabilityWhy do we care?
  • 4. flickr.com/photos/indraw/4857101224/ Most of your time is spent maintaining code
  • 5. Who cares?Your Employer Your Co-workers, Present and Future
  • 6. flickr.com/photos/protestphotos1/4726566233/ We all want to be rock stars "Dont mess with my process, man! Its about the music!"
  • 7. flickr.com/photos/the_junes/3120810156/ At work, youre part of a team Awesome happens when everyone is on the same page
  • 8. Maintainable code isUnderstandable Adaptable Debuggable Testable Intuitive Extendable
  • 9. Code Conventions Understandable Intuitive
  • 10. flickr.com/photos/29271559@N02/5799773313/ "Programs are meant to be read by humans and only incidentally for computers to execute." Donald Knuth
  • 11. flickr.com/photos/polinasergeeva/3052378826/ Tabs for indentation 4 spaces for indentation Indentation
  • 12. if (wl && wl.length) { for (i = 0, l = wl.length; i < l; ++i) { p = wl[i]; type = Y.Lang.type(r[p]); if (s.hasOwnProperty(p)) { if (merge && type == object) { Y.mix(r[p], s[p]);} else if (ov || !(p in r)) { r[p] = s[p]; } } } }
  • 13. if (wl && wl.length) { for (i = 0, l = wl.length; i < l; ++i) { p = wl[i]; type = Y.Lang.type(r[p]); if (s.hasOwnProperty(p)) { if (merge && type == object) { Y.mix(r[p], s[p]); } else if (ov || !(p in r)) { r[p] = s[p]; } } }}
  • 14. flickr.com/photos/polinasergeeva/3052378826/ Comments
  • 15. /** * Returns a new object containing all of the properties of * all the supplied objects. The properties from later objects * will overwrite those in earlier objects. Passing in a * single object will create a shallow copy of it. For a deep * copy, use clone. * @method merge * @for YUI * @param arguments {Object*} the objects to merge. * @return {object} the new merged object. */Y.merge = function() { var a = arguments, o = {}, i, l = a.length; for (i = 0; i < l; i = i + 1) { Y.mix(o, a[i], true); } return o;}; Every method
  • 16. if (mode) { switch (mode) { case 1: // proto to proto return Y.mix(r.prototype, s.prototype, ov, wl, 0, merge); case 2: // object to object and proto to proto Y.mix(r.prototype, s.prototype, ov, wl, 0, merge); break; // pass through case 3: // proto to static return Y.mix(r, s.prototype, ov, wl, 0, merge); case 4: // static to proto return Y.mix(r.prototype, s, ov, wl, 0, merge); default: // object to object is what happens below }} Difficult-to-understand code
  • 17. while (element &&(element = element[axis])){ //NOTE: assignment if ( (all || element[TAG_NAME]) && (!fn || fn(element)) ) { return element; }} Code that might seem to be wrong
  • 18. Namingflickr.com/photos/kaatje/243834320/
  • 19. Naming• Use logical names for variables and functions – Dont worry about length• Variable names should be nouns• Function names should begin with a verb (i.e. getName()) – Functions return booleans should begin with "is", such as isValid()• Avoid useless names such as foo and temp
  • 20. if (wl && wl.length) { for (i = 0, l = wl.length; i < l; ++i) { p = wl[i]; type = Y.Lang.type(r[p]); if (s.hasOwnProperty(p)) { if (merge && type == object) { Y.mix(r[p], s[p]); } else if (ov || !(p in r)) { r[p] = s[p]; } } }}
  • 21. Loose Coupling Adaptable Debuggable Extendable
  • 22. Front End LayersPresentation Behavior (CSS) (JavaScript) Base JS Data/Structure (HTML)
  • 23. Dont cross the streams
  • 24. <button onclick="doSomething()">Click Me</button> Keep JavaScript out of HTML
  • 25. var element = document.getElementById("container");element.innerHTML = "<div class="popup"></div>"; Keep HTML out of JavaScript
  • 26. .foo { width: expression(document.offsetWidth + "px");} Keep JavaScript out of CSS
  • 27. var element = document.getElementById("container");element.style.color = "red";element.style.cssText = "background:blue;border:1px solid red"; Keep CSS out of JavaScript
  • 28. Programming Practices Adaptable Debuggable Testable Extendable
  • 29. //the wrong way!!!function handleClick(event){ var popup = document.getElementById("popup"); popup.style.left = event.clientX + "px"; popup.style.top = event.clientY + "px"; popup.className = "reveal";} Event handlers should only handle events
  • 30. //better, but still wrongfunction handleClick(event){ showPopup(event);}function showPopup(event){ var popup = document.getElementById("popup"); popup.style.left = event.clientX + "px"; popup.style.top = event.clientY + "px"; popup.className = "reveal";} Dont pass the event object around
  • 31. //win!!function handleClick(event){ showPopup(event.clientX, event.clientY);}function showPopup(x, y){ var popup = document.getElementById("popup"); popup.style.left = x + "px"; popup.style.top = y + "px"; popup.className = "reveal";} Properly separated event handling
  • 32. //dont add new methodsArray.prototype.awYeah = function(){ alert("Aw yeah!");};//dont override methodsYUI.use = function(){ alert("Aw yeah!");}; Dont modify objects you dont own If you didnt define the object yourself, you dont own it
  • 33. nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/
  • 34. function handleClick(event){ showPopup(event.clientX, event.clientY);}function showPopup(x, y){ var popup = document.getElementById("popup"); popup.style.left = x + "px"; popup.style.top = y + "px"; popup.className = "reveal";} Avoid global functions and variables
  • 35. var Controller = { handleClick: function(event){ this.showPopup(event.clientX, event.clientY); }, showPopup: function (x, y){ var popup = document.getElementById("popup"); popup.style.left = x + "px"; popup.style.top = y + "px"; popup.className = "reveal"; }}; Avoid global functions and variables Create a single global (if necessary) and attach everything to it
  • 36. var Controller = { addClass: function(element, className){ element.className += " " + className; }}; Throw your own errors When you know a function will fail
  • 37. var Controller = { addClass: function(element, className){ if (!element) { throw new Error("addClass: 1st argument missing."); } element.className += " " + className; }}; Throw your own errors When you know a function will fail
  • 38. var Controller = { process: function(items){ if (items != null){ items.sort(); items.forEach(function(item){ //do something }); } }}; Avoid null comparisons
  • 39. var Controller = { process: function(items){ if (items instanceof Array){ items.sort(); items.forEach(function(item){ //do something }); } }}; Avoid null comparisons Test for precisely what you want to know if it matters
  • 40. Avoid null comparisons• Use instanceof to test for specific object types – object instanceof MyType• Use typeof to test for primitive types – typeof value == "string" – BEWARE: typeof null == "object"
  • 41. function validate(value) { if (!value) { alert("Invalid value"); location.href = "/errors/invalid.php"; }} Separate config data
  • 42. var config = { urls: { invalid: "/errors/invalid.php" }, strs: { invalidmsg: "Invalid value" }};function validate(value) { if (!value) { alert(config.strs.invalidmsg); location.href = config.urls.invalid; }} Separate config data
  • 43. Separate Config Data• All URLs needed by the JavaScript• Any strings that are displayed to the user• Any HTML that needs to be created from JavaScript• Settings (i.e., items per page)• Repeated unique values• Any value that may change in the future
  • 44. Build Process Understandable Testable
  • 45. Build Process Build
  • 46. Build Add/Remove Validate Debugging Code Concatenate Minify Files Files Generate DeployDocumentation Files
  • 47. BuildDevelopment Testing Deployment
  • 48. Recommendations• One object or object definition per file – Track dependencies• Use a build process to combines files – Determines correct order – Validates code (JSHint) – Minifies code (YUI Compressor) – Generate documentation (YUI Doc)
  • 49. http://www.julienlecomte.net/blog/2007/09/16/
  • 50. Recap
  • 51. Remember• Code conventions ensure everyones speaking the same language• Loose coupling of layers make changes and debugging easier• Good programming practices allow you to• Code organization and a build process help to bring sanity to an otherwise crazy process
  • 52. Questions?
  • 53. Etcetera• My blog: www.nczonline.net• Twitter: @slicknet• These Slides: slideshare.net/nzakas

×