Maintainable JavaScript 2012
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Maintainable JavaScript 2012

  • 53,694 views
Uploaded on

Writing code as an individual and writing code as part of the team are two very different things. Learn the tips and tricks for writing JavaScript code as part of the team so that your code will......

Writing code as an individual and writing code as part of the team are two very different things. Learn the tips and tricks for writing JavaScript code as part of the team so that your code will continue to work for years to come.

More in: Technology , Sports
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
53,694
On Slideshare
50,234
From Embeds
3,460
Number of Embeds
55

Actions

Shares
Downloads
836
Comments
3
Likes
143

Embeds 3,460

http://greenido.wordpress.com 1,351
http://rettamkrad.blogspot.tw 529
https://ocean.cybozu-dev.com 445
https://twitter.com 309
http://www.linkedin.com 97
http://sysoev.org 87
http://tungocman86.wordpress.com 79
http://s7at1c.ru 70
http://www.scoop.it 64
http://localhost 50
http://lanyrd.com 43
http://eventifier.co 42
https://ybanking.jira.com 40
https://ocean.s.cybozu-dev.com 34
http://guiec.blogspot.com 27
http://rettamkrad.blogspot.com 24
http://box.graffino.com 17
http://docs.intra.mixi.co.jp 15
http://us-w1.rockmelt.com 12
http://fellipe.com 11
http://lifeofjs.com 11
http://idosovaidoso.blogspot.com.br 9
http://tjx.local 8
http://notundefined.tumblr.com 8
http://rettamkrad.blogspot.hk 7
http://lnxdapmoweb01 7
http://pedromaciaspliego.blogspot.com.es 6
http://www.techgig.com 5
http://lad.webberry.org 5
http://mmoo4056.tistory.com 4
http://ttt.engir.com 4
http://tatianaib.wordpress.com 4
http://127.0.0.1 3
http://hire.chrisjlee.net 3
https://www.linkedin.com 3
http://posting.pagodabox.com 3
http://www.s7at1c.ru 2
http://115.112.206.131 2
http://beta.jolicloud.co 2
https://si0.twimg.com 2
http://www.guiec.blogspot.com 2
http://idosovaidoso.blogspot.com 1
http://www.njconsultandtravel.com 1
http://webcache.googleusercontent.com 1
http://bottlenose.local 1
http://engir.com 1
http://rettamkrad.blogspot.co.uk 1
http://kred.com 1
http://b.hatena.ne.jp 1
http://moderation.local 1

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
  • Over the past couple of years, we've seen JavaScript development earn recognition as a true discipline. The idea that you should architect your code, use patterns and good programming practices has really elevated the role of the front end engineer. In my opinion, part of this elevation has been the adoption of what has traditionally been considered back end methodologies. We now focus on performance and algorithms, there's unit testing for JavaScript, and so much more. One of the areas that I've seen a much slower than adoption that I'd like is in the area of error handling.How many people have an error handling strategy for their backend? How many have dashboards that display problems with uptime and performance? How many have anything similar for the front end?Typically, the front end has been this black hole of information. You may get a few customer reports here and there, but you have no information about what's going on, how often it's occurring, or how many people have been affected.
  • So what have we talked about? Maintainable JavaScript is made up of four components.First is Code Conventions that describe the format of the code you’re writing.Second is Loose Coupling – keeping HTML, JavaScript, and CSS on separate layers and keeping application logic out of event handlers.Third is Programming Practices that ensure your code is readable and easily debugged.Fourth is creating a Build Process

Transcript

  • 1. flickr.com/photos/jontysewell/4526861658/ Maintainable JavaScript Nicholas C. Zakas | Chief Architect, WellFurnished
  • 2. New
  • 3. @slicknet
  • 4. MaintainabilityWhy do we care?
  • 5. http://flickr.com/photos/indraw/4857101224/ Most of your time is spent maintaining code
  • 6. Maintainability Who cares?
  • 7. http://www.flickr.com/photos/jbiljr/1935937825/
  • 8. http://flickr.com/photos/protestphotos1/4726566233/ We all want to be rock stars "Dont mess with my process, man! Its about the music!"
  • 9. http://flickr.com/photos/12832008@N04/3027812968/
  • 10. MaintainabilityWhat is maintainable code?
  • 11. Maintainable code works for five years without major changes • Intuitive • Understandable • Adaptable • Extendable • Debuggable • Testablehttp://flickr.com/photos/simax/3390895249/
  • 12. Be kind to your futureself.Chris Eppstein,Creator of Compass
  • 13. Code Conventions ProgrammingCode Style Practices
  • 14. Code Style GuideCommunicating with each other through code
  • 15. Programs are meant to beread by humans andonly incidentally forcomputers to execute.H. Abelson and G. Sussman,The Structure and Interpretationof Computer Programs
  • 16. https://twitter.com/sh1mmer/status/21446028923
  • 17. http://javascript.crockford.com/code.html
  • 18. http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
  • 19. http://docs.jquery.com/JQuery_Core_Style_Guidelines
  • 20. http://dojotoolkit.org/community/styleGuide
  • 21. https://github.com/rwldrn/idiomatic.js/
  • 22. http://flickr.com/photos/polinasergeeva/3052378826/ Tabs for indentation 4 spaces for indentation
  • 23. 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]; } } } }
  • 24. 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]; } } }}
  • 25. https://twitter.com/slicknet/status/169903570047614977
  • 26. if (found) { doSomething(); doSomethingElse(); }else { doAThirdThing(); doAFourthThing(); }
  • 27. if (found) { doSomething(); doSomethingElse();} else { doAThirdThing(); doAFourthThing();}
  • 28. http://flickr.com/photos/polinasergeeva/3052378826/ Comments
  • 29. https://twitter.com/slicknet/statuses/3559283285
  • 30. /** * 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
  • 31. 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
  • 32. while (element &&(element = element[axis])){ //NOTE: assignment if ( (all || element[TAG_NAME]) && (!fn || fn(element)) ) { return element; }} Code that might seem to be wrong
  • 33. Naminghttp://flickr.com/photos/kaatje/243834320/
  • 34. 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" or "has", such as isValid() or hasItem()• Avoid useless names such as foo and temp
  • 35. 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]; } } }}
  • 36. // Variables, functions, properties methodsvar myName = "Nicholas";function sayName() { alert(myName);}var person = { name: "Nicholas", sayName: function() { alert(this.name); }}; Camel Casing
  • 37. What about acronyms?
  • 38. var element = document.getElementById("my-div");element.innerHTML = "Hello world!"; WTF?var xhr = new XMLHttpRequest(); No, seriously WTF? Camel Casing
  • 39. // Constant-like variablesvar HOVER_CLASS = "mouse-over";// Constructorsfunction Person(name) { this.name = name;}var me = new Person("Nicholas"); Camel Casing- Exceptions
  • 40. Programming PracticesSmall patterns for common problems
  • 41. There are two ways ofconstructing a softwaredesign: One way is to make itso simple that there areobviously no deficiencies andthe other way is to make it socomplicated that there are noobvious deficiencies.C.A.R. Hoare,Quicksort Developer
  • 42. Front End LayersPresentation Behavior (CSS) (JavaScript) Base JS Data/Structure (HTML)
  • 43. Don’t cross thestreams
  • 44. <button onclick="doSomething()">Click Me</button> Keep JavaScript out of HTML
  • 45. var element = document.getElementById("container");element.innerHTML = "<div class="popup"></div>"; Keep HTML out of JavaScript
  • 46. .foo { width: expression(document.offsetWidth + "px");} Keep JavaScript out of CSS
  • 47. var element = document.getElementById("container");element.style.color = "red";element.style.cssText = "background:blue;border:1px solid red"; Keep CSS out of JavaScript
  • 48. //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
  • 49. //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
  • 50. //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
  • 51. //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
  • 52. http://nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/
  • 53. 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
  • 54. 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
  • 55. var Controller = { addClass: function(element, className){ element.className += " " + className; }}; Throw your own errors When you know a function will fail
  • 56. 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
  • 57. var Controller = { process: function(items){ if (items != null){ items.sort(); items.forEach(function(item){ //do something }); } }}; Avoid null comparisons
  • 58. 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
  • 59. 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"
  • 60. function validate(value) { if (!value) { alert("Invalid value"); location.href = "/errors/invalid.php"; }} Separate config data
  • 61. 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
  • 62. 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
  • 63. https://github.com/nzakas/props2js
  • 64. AutomationMake everyone’s life easier
  • 65. Build Process Build
  • 66. Build Add/Remove Validate Debugging Code Concatenate Test Code Files Generate Minify FilesDocumentation Deploy Files
  • 67. Add/Remove Debugginghttps://github.com/moxiecode/js-build-tools
  • 68. Generate Documentationhttp://usejsdoc.org
  • 69. Generate Documentationhttp://yuilibrary.com/projects/yuidoc/
  • 70. Generate Documentationhttp://jashkenas.github.com/docco/
  • 71. Validate Codehttp://jslint.com
  • 72. Validate Codehttp://jshint.com
  • 73. Minify Fileshttp://yuilibrary.com/projects/yuicompressor/
  • 74. Minify Fileshttps://github.com/mishoo/UglifyJS/
  • 75. Minify Fileshttps://developers.google.com/closure/compiler/
  • 76. Buildhttps://ant.apache.org
  • 77. Buildhttp://www.julienlecomte.net/blog/2007/09/16/
  • 78. Buildhttps://github.com/cowboy/grunt
  • 79. Buildhttp://weblog.bocoup.com/introducing-grunt/
  • 80. BuildDevelopment Testing Deployment Add/Remove Add/Remove Add/Remove Debugging Debugging Debugging Validate Validate Validate Code Code Code Test Code Test Code Test Code Generate Concatenate ConcatenateDocumentation Files Files Minify Files Minify Files Deploy Files
  • 81. Recap
  • 82. Remember• Code style guidelines ensure everyones speaking the same language• Loose coupling of layers make changes and debugging easier• Good programming practices allow for easier debugging• Code organization and automation help to bring sanity to an otherwise crazy process
  • 83. https://twitter.com/kylerichter/status/15101151292694529
  • 84. Etcetera•My company: wellfurnished.com•My blog: nczonline.net•Twitter: @slicknet•These Slides: slideshare.net/nzakas