flickr.com/photos/jontysewell/4526861658/                Maintainable JavaScript                   Nicholas C. Zakas | Chi...
New
@slicknet
MaintainabilityWhy do we care?
http://flickr.com/photos/indraw/4857101224/            Most of your time is spent maintaining code
Maintainability  Who cares?
http://www.flickr.com/photos/jbiljr/1935937825/
http://flickr.com/photos/protestphotos1/4726566233/                               We all want to be rock stars            ...
http://flickr.com/photos/12832008@N04/3027812968/
MaintainabilityWhat is maintainable code?
Maintainable code works for      five years without major      changes                                             • Intui...
Be kind to your futureself.Chris Eppstein,Creator of Compass
Code Conventions                                ProgrammingCode Style                        Practices
Code Style GuideCommunicating with each other through               code
Programs are meant to beread by humans andonly incidentally forcomputers to execute.H. Abelson and G. Sussman,The Structur...
https://twitter.com/sh1mmer/status/21446028923
http://javascript.crockford.com/code.html
http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
http://docs.jquery.com/JQuery_Core_Style_Guidelines
http://dojotoolkit.org/community/styleGuide
https://github.com/rwldrn/idiomatic.js/
http://flickr.com/photos/polinasergeeva/3052378826/                                                        Tabs for       ...
if (wl && wl.length) {            for (i = 0, l = wl.length; i < l; ++i) {         p = wl[i];         type = Y.Lang.type(r...
if (wl && wl.length) {    for (i = 0, l = wl.length; i < l; ++i) {        p = wl[i];        type = Y.Lang.type(r[p]);     ...
https://twitter.com/slicknet/status/169903570047614977
if (found) { doSomething(); doSomethingElse(); }else { doAThirdThing(); doAFourthThing(); }
if (found) {    doSomething();    doSomethingElse();} else {    doAThirdThing();    doAFourthThing();}
http://flickr.com/photos/polinasergeeva/3052378826/                                                      Comments
https://twitter.com/slicknet/statuses/3559283285
/** * Returns a new object containing all of the properties of * all the supplied objects. The properties from later objec...
if (mode) {    switch (mode) {        case 1: // proto to proto            return Y.mix(r.prototype, s.prototype, ov, wl, ...
while (element &&(element = element[axis])){ //NOTE: assignment    if ( (all || element[TAG_NAME]) &&       (!fn || fn(ele...
Naminghttp://flickr.com/photos/kaatje/243834320/
Naming• Use logical names for variables and functions   – Dont worry about length• Variable names should be nouns• Functio...
if (wl && wl.length) {    for (i = 0, l = wl.length; i < l; ++i) {        p = wl[i];        type = Y.Lang.type(r[p]);     ...
// Variables, functions, properties methodsvar myName = "Nicholas";function sayName() {    alert(myName);}var person = {  ...
What about acronyms?
var element = document.getElementById("my-div");element.innerHTML = "Hello world!";      WTF?var xhr = new XMLHttpRequest(...
// Constant-like variablesvar HOVER_CLASS = "mouse-over";// Constructorsfunction Person(name) {    this.name = name;}var m...
Programming PracticesSmall patterns for common problems
There are two ways ofconstructing a softwaredesign: One way is to make itso simple that there areobviously no deficiencies...
Front End LayersPresentation      Behavior    (CSS)       (JavaScript)                 Base JS       Data/Structure       ...
Don’t cross thestreams
<button onclick="doSomething()">Click Me</button>      Keep JavaScript out of HTML
var element = document.getElementById("container");element.innerHTML = "<div class="popup"></div>";              Keep HTML...
.foo {    width: expression(document.offsetWidth + "px");}               Keep JavaScript out of CSS
var element = document.getElementById("container");element.style.color = "red";element.style.cssText = "background:blue;bo...
//the wrong way!!!function handleClick(event){    var popup = document.getElementById("popup");    popup.style.left = even...
//better, but still wrongfunction handleClick(event){    showPopup(event);}function showPopup(event){    var popup = docum...
//win!!function handleClick(event){    showPopup(event.clientX, event.clientY);}function showPopup(x, y){    var popup = d...
//dont add new methodsArray.prototype.awYeah = function(){    alert("Aw yeah!");};//dont override methodsYUI.use = functio...
http://nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/
function handleClick(event){    showPopup(event.clientX, event.clientY);}function showPopup(x, y){    var popup = document...
var Controller = {    handleClick: function(event){        this.showPopup(event.clientX, event.clientY);    },     showPop...
var Controller = {    addClass: function(element, className){        element.className += " " + className;    }};         ...
var Controller = {    addClass: function(element, className){        if (!element) {            throw new Error("addClass:...
var Controller = {    process: function(items){        if (items != null){            items.sort();            items.forEa...
var Controller = {    process: function(items){        if (items instanceof Array){            items.sort();            it...
Avoid null comparisons• Use instanceof to test for specific object types   – object instanceof MyType• Use typeof to test ...
function validate(value) {    if (!value) {        alert("Invalid value");        location.href = "/errors/invalid.php";  ...
var config = {    urls: {        invalid: "/errors/invalid.php"    },    strs: {        invalidmsg: "Invalid value"    }};...
Separate Config Data•   All URLs needed by the JavaScript•   Any strings that are displayed to the user•   Any HTML that n...
https://github.com/nzakas/props2js
AutomationMake everyone’s life easier
Build Process  Build
Build Add/Remove               Validate  Debugging                Code Concatenate                         Test Code    Fi...
Add/Remove                                          Debugginghttps://github.com/moxiecode/js-build-tools
Generate                      Documentationhttp://usejsdoc.org
Generate                                         Documentationhttp://yuilibrary.com/projects/yuidoc/
Generate                                     Documentationhttp://jashkenas.github.com/docco/
Validate                     Codehttp://jslint.com
Validate                     Codehttp://jshint.com
Minify Fileshttp://yuilibrary.com/projects/yuicompressor/
Minify Fileshttps://github.com/mishoo/UglifyJS/
Minify Fileshttps://developers.google.com/closure/compiler/
Buildhttps://ant.apache.org
Buildhttp://www.julienlecomte.net/blog/2007/09/16/
Buildhttps://github.com/cowboy/grunt
Buildhttp://weblog.bocoup.com/introducing-grunt/
BuildDevelopment      Testing       Deployment Add/Remove     Add/Remove      Add/Remove  Debugging      Debugging       D...
Recap
Remember• Code style guidelines ensure everyones speaking  the same language• Loose coupling of layers make changes and  d...
https://twitter.com/kylerichter/status/15101151292694529
Etcetera•My company:     wellfurnished.com•My blog:        nczonline.net•Twitter:        @slicknet•These Slides:   slidesh...
Maintainable JavaScript 2012
Upcoming SlideShare
Loading in...5
×

Maintainable JavaScript 2012

57,436

Published 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 continue to work for years to come.

Published in: Technology, Sports
3 Comments
152 Likes
Statistics
Notes
No Downloads
Views
Total Views
57,436
On Slideshare
0
From Embeds
0
Number of Embeds
31
Actions
Shares
0
Downloads
910
Comments
3
Likes
152
Embeds 0
No embeds

No notes for slide
  • Over the past couple of years, we&apos;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&apos;s unit testing for JavaScript, and so much more. One of the areas that I&apos;ve seen a much slower than adoption that I&apos;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&apos;s going on, how often it&apos;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
  • Maintainable JavaScript 2012

    1. 1. flickr.com/photos/jontysewell/4526861658/ Maintainable JavaScript Nicholas C. Zakas | Chief Architect, WellFurnished
    2. 2. New
    3. 3. @slicknet
    4. 4. MaintainabilityWhy do we care?
    5. 5. http://flickr.com/photos/indraw/4857101224/ Most of your time is spent maintaining code
    6. 6. Maintainability Who cares?
    7. 7. http://www.flickr.com/photos/jbiljr/1935937825/
    8. 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. 9. http://flickr.com/photos/12832008@N04/3027812968/
    10. 10. MaintainabilityWhat is maintainable code?
    11. 11. Maintainable code works for five years without major changes • Intuitive • Understandable • Adaptable • Extendable • Debuggable • Testablehttp://flickr.com/photos/simax/3390895249/
    12. 12. Be kind to your futureself.Chris Eppstein,Creator of Compass
    13. 13. Code Conventions ProgrammingCode Style Practices
    14. 14. Code Style GuideCommunicating with each other through code
    15. 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. 16. https://twitter.com/sh1mmer/status/21446028923
    17. 17. http://javascript.crockford.com/code.html
    18. 18. http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
    19. 19. http://docs.jquery.com/JQuery_Core_Style_Guidelines
    20. 20. http://dojotoolkit.org/community/styleGuide
    21. 21. https://github.com/rwldrn/idiomatic.js/
    22. 22. http://flickr.com/photos/polinasergeeva/3052378826/ Tabs for indentation 4 spaces for indentation
    23. 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. 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. 25. https://twitter.com/slicknet/status/169903570047614977
    26. 26. if (found) { doSomething(); doSomethingElse(); }else { doAThirdThing(); doAFourthThing(); }
    27. 27. if (found) { doSomething(); doSomethingElse();} else { doAThirdThing(); doAFourthThing();}
    28. 28. http://flickr.com/photos/polinasergeeva/3052378826/ Comments
    29. 29. https://twitter.com/slicknet/statuses/3559283285
    30. 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. 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. 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. 33. Naminghttp://flickr.com/photos/kaatje/243834320/
    34. 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. 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. 36. // Variables, functions, properties methodsvar myName = "Nicholas";function sayName() { alert(myName);}var person = { name: "Nicholas", sayName: function() { alert(this.name); }}; Camel Casing
    37. 37. What about acronyms?
    38. 38. var element = document.getElementById("my-div");element.innerHTML = "Hello world!"; WTF?var xhr = new XMLHttpRequest(); No, seriously WTF? Camel Casing
    39. 39. // Constant-like variablesvar HOVER_CLASS = "mouse-over";// Constructorsfunction Person(name) { this.name = name;}var me = new Person("Nicholas"); Camel Casing- Exceptions
    40. 40. Programming PracticesSmall patterns for common problems
    41. 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. 42. Front End LayersPresentation Behavior (CSS) (JavaScript) Base JS Data/Structure (HTML)
    43. 43. Don’t cross thestreams
    44. 44. <button onclick="doSomething()">Click Me</button> Keep JavaScript out of HTML
    45. 45. var element = document.getElementById("container");element.innerHTML = "<div class="popup"></div>"; Keep HTML out of JavaScript
    46. 46. .foo { width: expression(document.offsetWidth + "px");} Keep JavaScript out of CSS
    47. 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. 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. 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. 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. 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. 52. http://nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/
    53. 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. 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. 55. var Controller = { addClass: function(element, className){ element.className += " " + className; }}; Throw your own errors When you know a function will fail
    56. 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. 57. var Controller = { process: function(items){ if (items != null){ items.sort(); items.forEach(function(item){ //do something }); } }}; Avoid null comparisons
    58. 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. 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. 60. function validate(value) { if (!value) { alert("Invalid value"); location.href = "/errors/invalid.php"; }} Separate config data
    61. 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. 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. 63. https://github.com/nzakas/props2js
    64. 64. AutomationMake everyone’s life easier
    65. 65. Build Process Build
    66. 66. Build Add/Remove Validate Debugging Code Concatenate Test Code Files Generate Minify FilesDocumentation Deploy Files
    67. 67. Add/Remove Debugginghttps://github.com/moxiecode/js-build-tools
    68. 68. Generate Documentationhttp://usejsdoc.org
    69. 69. Generate Documentationhttp://yuilibrary.com/projects/yuidoc/
    70. 70. Generate Documentationhttp://jashkenas.github.com/docco/
    71. 71. Validate Codehttp://jslint.com
    72. 72. Validate Codehttp://jshint.com
    73. 73. Minify Fileshttp://yuilibrary.com/projects/yuicompressor/
    74. 74. Minify Fileshttps://github.com/mishoo/UglifyJS/
    75. 75. Minify Fileshttps://developers.google.com/closure/compiler/
    76. 76. Buildhttps://ant.apache.org
    77. 77. Buildhttp://www.julienlecomte.net/blog/2007/09/16/
    78. 78. Buildhttps://github.com/cowboy/grunt
    79. 79. Buildhttp://weblog.bocoup.com/introducing-grunt/
    80. 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. 81. Recap
    82. 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. 83. https://twitter.com/kylerichter/status/15101151292694529
    84. 84. Etcetera•My company: wellfurnished.com•My blog: nczonline.net•Twitter: @slicknet•These Slides: slideshare.net/nzakas
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×