Writing Maintainable and Reusable JavaScript

Writing Maintainable and Reusable JavaScript

It’s really easy for JavaScript files in a theme or plugin to quickly become a big, hairy mess. So let’s take a look at how to structure JavaScript code in a way that makes it easier to read and understand, easier to maintain, and prevents pollution of the global namespace. We’ll cover modular JavaScript structure and writing plugins.

9c9bcdbab2f098f69b3adadde6ee2936?s=128

Natalie MacLees

November 08, 2014
Tweet

Transcript

  1. Writing Maintainable & Reusable JavaScript by Natalie MacLees @nataliemac |

    nataliemac.com
  2. Why is maintainability important?

  3. JavaScript mistakes you’re probably making

  4. Writing all your code inside document ready jQuery(document).ready(function($){ function slideShow()

    { // some code that makes a slideshow } ! function newsTicker() { // some code that makes a news ticker } ... });
  5. Using global scope for all your variables and functions var

    newText = ‘Hello World’; ! function addText() { var container = $(‘textContainer’); container.text(newText); } ! var height = window.height();
  6. Inconsistently using style conventions var newText = ‘Hello World!”; !

    var some_other_text = “Hi there!”; ! var yetSomeMoreText = “Bonjour!”;
  7. Not maintaining separation <a href=“#” onclick=“doSomething();”>Click me!</a> $(‘a’).css({
 ‘color’: ‘green’;


    ‘fontSize’: ‘2em’;
 }); var lightbox = $(‘<div class=“overlay”></div><div class=“lightbox”><img src=“”/><div class=“lightbox- title”></div></div>’);
  8. The wild, wild West of JavaScript

  9. Understandable Future-proof Readable Modifiable Extensible Testable What does maintainable &

    reusable mean?
  10. Writing better JavaScript 1 2 3 4 5 Style conventions

    Programming practices Modular pattern jQuery plugins Automation
  11. 1 Style conventions

  12. Spaces vs tabs

  13. Keep lines as short as possible if ( tod ==

    ‘morning’ ) { $(‘.greeting’).text(‘Good morning’) } else { $(‘.greeting’).text(‘Good afternoon!’) } ! $ (‘ul’).slideDown().find(‘li’).addClass(‘open’).prepe nd(‘+’).end().addClass(‘parent-open’);
  14. Keep lines as short as possible $(‘ul’) .slideDown() .find(‘li’) .addClass(‘open’)

    .prepend(‘+’) .end() .addClass(‘parent-open’);
  15. Use comments like salt in soup

  16. Use logical names for functions and variables (even if they’re

    long)
  17. Use camelCase

  18. camelCase & abbreviations and acronynms getElementById() innerHTML() XMLHttpRequest()

  19. 2 Programming practices

  20. Keep layers separate CSS: .highlight {
 color: green;
 fontSize: 2em;


    } JavaScript: $(‘a’).addClass(‘highlight’);
  21. Keep layers separate <div class="entry"> <h1>{{title}}</h1> <div class="body"> {{body}} </div>

    </div>
  22. Don’t modify objects you don’t own

  23. Event handlers should only handle events $(‘.next’).on(‘click’, function(){ var slider

    = $(‘#slider’), currentSlide = slider.find(‘.current’), nextSlide = currentSlide.next(); currentSlide.fadeOut(); nextSlide.fadeIn(); });
  24. Event handlers should only handle events $(‘.next’).on(‘click’, function(){ nextSlide(); });

    ! function nextSlide() { // code to advance to next slide here }
  25. Throw your own errors Twitlicious.addTweets = function(container) { if (

    container instanceof jQuery) { container.append(Twitlicious.tweets); } else { throw new Error “addTweets: This is not a jQuery object!”; } }
  26. Separate config data var config = { url: ‘https://api.twitter.com/...', tweetsToShow:

    5, tweetContainer: $(‘#tweets’) };
  27. Avoid global functions & variables

  28. 3 Modular Pattern

  29. Object literal var projectName = { config: { numberofTweets: 5,

    url: ‘http://api.twitter.com...', container: $(‘tweets’) }, init: function() { // get everything going }, ...
  30. Object literal jQuery(function(){ projectName.init(); }; ! var projectName = {

    config: { ... }, init: function() { // initialize the project } }
  31. Immediately invoked function expression (IIFE) ;(function ($, projectName, undefined) {

    var linkClick = function() { // private $(‘a’).on(‘click’, function(){ //do something when links are clicked }); }; projectName.init = function() { // public linkClick(); }; }(jQuery, window.projectName = window.projectName || {})); ! jQuery(function(){ projectName.init(); });
  32. 4 jQuery plugins

  33. Use an immediately invoked function expression ;(function($){ $.fn.venturaSlider = function(options){

    // Plugin code goes here } })(jQuery);
  34. window, document, undefined ;(function($, window, document, undefined){ $.fn.venturaSlider = function(options){

    // Plugin code goes here } })(jQuery, window, document);
  35. Iterate over each item in the collection ;(function($, window, document,

    undefined){ $.fn.venturaSlider = function(options){ this.each(function(){ // Do something to each item }); } })(jQuery, window, document);
  36. Use .data() to store instance details ;(function($, window, document, undefined){

    $.fn.venturaSlider = function(options){ this.each(function(){ var $this = $(this); $this.data(‘current’, 1); }); } })(jQuery, window, document);
  37. Allow customization & use extend() ;(function($, window, document, undefined){ $.fn.venturaSlider

    = function(options){ var opts = $.extend( {}, $.fn.venturaSlider.defaults, options); ... } $.fn.venturaSlider.defaults = { // Define default settings }; })(jQuery, window, document);
  38. Return the jQuery object for chaining ;(function($, window, document, undefined){

    $.fn.venturaSlider = function(options){ var opts = $.extend( {}, $.fn.venturaSlider.defaults, options); ... return this; } $.fn.venturaSlider.defaults = {}; })(jQuery, window, document);
  39. 5 Automation

  40. Break JavaScript into multiple files

  41. Minify, compress, & deploy

  42. Maintainable & reusable code matters 1 2 3 4 5

    Style conventions Programming practices Modular pattern jQuery plugins Automation
  43. –Rick Osborne, creator of TorrentSpy “Always code as if the

    person who ends up maintaining your code is a violent psychopath who knows where you live.”
  44. –Chris Eppstein, creator of Compass “Be kind to your future

    self.”
  45. Thank you! Questions?