SlideShare a Scribd company logo
1 of 29
Download to read offline
Cleaner, Leaner, Meaner
            Refactoring your JavaScript
            Rebecca Murphey • @rmurphey • rebeccamurphey.com

Thursday, December 2, 2010
http://github.com/rmurphey/refactor-jquery




                                                            2
Thursday, December 2, 2010
“... changing a software system in such a way
              that it does not alter the external behavior
              of the code yet improves its internal
              structure.”
                                         Martin Fowler, “Refactoring”




                                                                        3
Thursday, December 2, 2010
Why Refactor?
               Hint: Not just because it’s fun.
Thursday, December 2, 2010
“When you sit down and solve a
                             problem, that solution is
                             merely a rst draft.”
                                   Stoyan Stefanov, “JavaScript Patterns”




                                                                            5
Thursday, December 2, 2010
Internal rewards
               Increase maintainability
               Increase extensibility & reusability


               User experience rewards
               Improve page performance
               Increase testability (reduce bugs)



                                                      6
Thursday, December 2, 2010
Put another way: Refactoring will make your
               users happier, make your code cheaper to work
               with, or both.

                                                               7
Thursday, December 2, 2010
JavaScript
                             Code Smells
                             8 tell-tale signs your code needs some TLC




Thursday, December 2, 2010
$('#showMessage').click(function() {
                        $('<div>' +
                          '<h1>' + $('#messageTitle').val() + '</h1>' +
                          '<p>' + $('#messageText').val() + '</p>' +
                          '</div>')
                          .appendTo('#messageContainer')
                      });

                      // MINTY FRESH: Use templates instead
                      <script type="text/x-jquery-tmpl" id="messageTemplate">
                        <div>
                          <h1>${title}</h1>
                          <p>${text}</p>
                        </div>
                      </script>

                      $('#messageTemplate').template('messageTemplate');

                      $.tmpl('messageTemplate', {
                        title : $('#messageTitle').val(),
                        text : $('#messageText').val()
                      })
                      .appendTo('#messageContainer');




             HTML in your JavaScript
                                                                                9
Thursday, December 2, 2010
http://api.jquery.com/category/plugins/templates/
               http://github.com/janl/mustache.js/
               http://documentcloud.github.com/underscore/


                                                                   10
Thursday, December 2, 2010
$('p.special').click(function() {
                         $(this).css({
                           'color' : 'red',
                           'font-weight' : 'bold'
                         });
                      })

                      // MINTY FRESH: Keep presentation information in CSS
                      p.extraSpecial {
                        color: red;
                        font-weight: bold;
                      }

                      $('p.special').click(function() {
                        $(this).addClass('extraSpecial');
                      });




             Changing style information in JavaScript
                                                                             11
Thursday, December 2, 2010
function isItemInArray(item, arr) {
                        var inArray = false,
                            len = arr.length;

                          for (var i = 0; i < len; i++) {
                            if (item == arr[i]) {
                              inArray = true;
                            }
                          }

                          return inArray;
                      }

                      // MINTY FRESH: Use jQuery!
                      function isItemInArray(item, arr) {
                        return $.inArray(item, arr) > -1;
                      }




             Duplication of existing jQuery methods
                                                            12
Thursday, December 2, 2010
http://api.jquery.com/category/utilities/
               http://api.jquery.com/category/miscellaneous/




                                                               13
Thursday, December 2, 2010
$('a.thinger').each(function() {
                         $(this).attr('href', $(this).attr('href') + '?ajax=true');
                      });
                      $('a.thinger').hide();
                      $('#myButton').click(function(){
                         $('a.thinger').show();
                      })

                      // MINTY FRESH: Use the chain and setter functions!
                      var thingers = $('a.thinger'), // store selection in a var
                          button = $('#myButton');   // just in case!

                      thingers.attr('href', function(idx, oldVal) {
                        // pass a setter function & avoid the need
                        // to iterate over matches
                        return oldVal + '?ajax=true';
                      }).hide();

                      button.click(function() {
                        thingers.show();
                      });




             Repetition that jQuery lets you avoid
                                                                                      14
Thursday, December 2, 2010
$(document).ready(function() {
                        $('#enableAwesome').click(function() {
                          $('ul.foo li').each(function() {
                            var li = $(this);

                               li.data('name', li.html())
                                 .find('a.remove').click(function(e) {
                                   $.ajax({
                                      url : $(this).attr('href'),
                                      dataType : 'json',
                                      type : 'post',
                                      success : function(resp) {
                                        if (resp.ok) { li.remove(); }
                                      },
                                      error : console.log
                                   })
                                   e.preventDefault();
                                 });
                          })
                        });
                      });




             Deeply nested anonymous functions
                                                                         15
Thursday, December 2, 2010
// MINTY FRESH: Isolate functionality into an object with methods
                      var awesome = {
                        enableListItem : function() {
                           var li = $(this);
                          li.data('name', li.html());
                        },

                           removeListItem : function() {
                             var a = $(this),
                                 li = a.closest('li');

                             awesome.removeOnServer({
                                url : a.attr('href'),
                                success : function(resp) {
                                  if (resp.ok) { li.remove(); }
                                }
                              });
                           },

                           removeOnServer : function (config) {
                             var defaults = {
                                   type : 'post',
                                   dataType : 'json',
                                   error : console.log
                                 },
                                 settings = $.extend({}, defaults, config);

                               if (!settings.url) { return; }
                               $.ajax(config);
                           }
                      };




                                                                                          16
Thursday, December 2, 2010
$(document).ready(function() {
                        $('#enableAwesome').click(function() {
                          $('ul.foo li')
                            .each(awesome.enableListItem)
                            .delegate('a.remove', 'click', awesome.removeListItem);
                        });
                      });




                                                                                      17
Thursday, December 2, 2010
// SMELLY: Overtesting for truthiness
                      if (errorMsg != null && errorMsg.length > 0) {
                        // ...
                      }

                      // MINTY FRESH: Be as terse as you can
                      if (errorMsg && errorMsg.length) {
                        // ...
                      }




             Overtesting for truthiness
                                                                       18
Thursday, December 2, 2010
// SMELLY
                      if (total == null || total == "0") {
                        // ...
                      }

                      // MINTY FRESH
                      if (!parseInt(total, 10)) {
                        // ...
                      }




                                                             19
Thursday, December 2, 2010
// SMELLY
                      if (price == null) {
                        // ...
                      } else if(discountPrice != null && price == discountPrice) {
                        // ...
                      }

                      // MINTY FRESH
                      if (!price) {
                        // ...

                      // we already know that price isn't null,
                      // so why test if discountPrice is? if it's
                      // equal to price, we know it's not null
                      } else if (price == discountPrice) {
                        // ...
                      }




                                                                                     20
Thursday, December 2, 2010
function isItABigNumber(num) {
                        if(num > 5000) {
                          $('#myContainer').html('<p>It was a big number</p>');
                          $('#myInput').val(num);
                          $('.thinger').hide();
                        } else {
                          $('#myContainer').html('<p>It was not a big number</p>');
                          $('#myInput').val('');
                          $('.thinger').show();
                        }
                      }

                      // MINTY FRESH: Only repeat what needs repeating
                      function isItABigNumber(num) {
                        var big = num > 5000;

                          $('#myContainer').html(big ?
                            '<p>It was a big number</p>' :
                            '<p>It was not a big number</p>');
                          $('#myInput').val(big ? num : '');
                          $('.thinger')[big ? 'hide' : 'show']();
                      }




             Repetitive logic blocks
                                                                                      21
Thursday, December 2, 2010
function crazyConcatenation(selector, word1, word2, word3, repeat) {
                        var arr = [],
                            words = [],
                            joinedWords;

                          if (selector == null) { return; }
                          if (word1 == null) { return; }

                          if (word2 != null) { words.push(word2); }
                          if (word3 != null) { words.push(word3); }
                          if (!repeat) { repeat = 5; }

                          joinedWords = words.join(', ');

                          while (repeat--) { arr.push(joinedWords); }

                          $(selector).html(arr.join('<br/>'))
                      }

                      crazyConcatenation('#foo', 'Hello', null, null, 5);




             Passing a lot of arguments to a function
                                                                                             22
Thursday, December 2, 2010
// MINTY FRESH: Using an object instead
                      function crazyConcatenation(config) {
                        // indicate clearly what's required
                        if (
                          !config.selector ||
                          !config.words ||
                          !config.words.length
                        ) { return; }

                          var defaults = { repeat : 5 },
                              settings = $.extend({}, defaults, config),
                              joinedWords = settings.words.join(', ');

                          while (settings.repeat--) {
                            arr.push(joinedWords);
                          }

                          $(settings.selector).html(arr.join('<br/>'))
                      }

                      crazyConcatenation({
                        selector : '#foo',
                        words : [ 'foo', 'bar', 'baz' ],
                        repeat : 20
                      });




                                                                           23
Thursday, December 2, 2010
Advanced Moves
               Common patterns for improving your code
Thursday, December 2, 2010
“Writing to be read means writing code ... with
               the idea that someone else will read it. is
               fact alone will make you edit and think of better
               ways to solve the problem you have at hand.”
                                       Stoyan Stefanov, “JavaScript Patterns”


                                                                                25
Thursday, December 2, 2010
example add the same behavior to similar
               content without depending on IDs




                                                          26
Thursday, December 2, 2010
example cache XHR responses, and create an
               API to a server-side service




                                                            27
Thursday, December 2, 2010
example refactor a portlet
                             to use the jQuery UI widget
                             factory




                                                           28
Thursday, December 2, 2010
rebeccamurphey.com

                             blog.rebeccamurphey.com

                             @rmurphey

                             http://github.com/rmurphey/refactor-jquery

                             http://pinboard.in/u:rmurphey/t:refactor/


                             Presented at the 2010 Rich Web Experience




                                                                          29
Thursday, December 2, 2010

More Related Content

What's hot

Kick start with j query
Kick start with j queryKick start with j query
Kick start with j queryMd. Ziaul Haq
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitRebecca Murphey
 
Command-Oriented Architecture
Command-Oriented ArchitectureCommand-Oriented Architecture
Command-Oriented ArchitectureLuiz Messias
 
Ext GWT 3.0 Theming and Appearances
Ext GWT 3.0 Theming and AppearancesExt GWT 3.0 Theming and Appearances
Ext GWT 3.0 Theming and AppearancesSencha
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End DevsRebecca Murphey
 
Drupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of UsageDrupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of UsageRonald Ashri
 
Building Sencha Themes
Building Sencha ThemesBuilding Sencha Themes
Building Sencha ThemesSencha
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyHuiyi Yan
 
Transparent Object Persistence with FLOW3
Transparent Object Persistence with FLOW3Transparent Object Persistence with FLOW3
Transparent Object Persistence with FLOW3Karsten Dambekalns
 
2013-03-23 - NoSQL Spartakiade
2013-03-23 - NoSQL Spartakiade2013-03-23 - NoSQL Spartakiade
2013-03-23 - NoSQL SpartakiadeJohannes Hoppe
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
Drupal csu-open atriumname
Drupal csu-open atriumnameDrupal csu-open atriumname
Drupal csu-open atriumnameEmanuele Quinto
 
Drupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comDrupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comJD Leonard
 

What's hot (19)

Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
 
jQuery
jQueryjQuery
jQuery
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development Toolkit
 
Dojo Confessions
Dojo ConfessionsDojo Confessions
Dojo Confessions
 
Command-Oriented Architecture
Command-Oriented ArchitectureCommand-Oriented Architecture
Command-Oriented Architecture
 
Ext GWT 3.0 Theming and Appearances
Ext GWT 3.0 Theming and AppearancesExt GWT 3.0 Theming and Appearances
Ext GWT 3.0 Theming and Appearances
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End Devs
 
Drupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of UsageDrupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of Usage
 
Building Sencha Themes
Building Sencha ThemesBuilding Sencha Themes
Building Sencha Themes
 
Email Program By Marcelo
Email Program By MarceloEmail Program By Marcelo
Email Program By Marcelo
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journey
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
Transparent Object Persistence with FLOW3
Transparent Object Persistence with FLOW3Transparent Object Persistence with FLOW3
Transparent Object Persistence with FLOW3
 
2013-03-23 - NoSQL Spartakiade
2013-03-23 - NoSQL Spartakiade2013-03-23 - NoSQL Spartakiade
2013-03-23 - NoSQL Spartakiade
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Drupal csu-open atriumname
Drupal csu-open atriumnameDrupal csu-open atriumname
Drupal csu-open atriumname
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Drupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comDrupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.com
 

Similar to Cleaner, Leaner, Meaner: Refactoring your jQuery

international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
Organizing Code with JavascriptMVC
Organizing Code with JavascriptMVCOrganizing Code with JavascriptMVC
Organizing Code with JavascriptMVCThomas Reynolds
 
jQuery - Tips And Tricks
jQuery - Tips And TricksjQuery - Tips And Tricks
jQuery - Tips And TricksLester Lievens
 
Jquery optimization-tips
Jquery optimization-tipsJquery optimization-tips
Jquery optimization-tipsanubavam-techkt
 
jQuery Anti-Patterns for Performance
jQuery Anti-Patterns for PerformancejQuery Anti-Patterns for Performance
jQuery Anti-Patterns for PerformanceAndrás Kovács
 
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 JavascriptjQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 JavascriptDarren Mothersele
 
jQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't KnowjQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't Knowgirish82
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionPaul Irish
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsJarod Ferguson
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuerysergioafp
 
A Rich Web experience with jQuery, Ajax and .NET
A Rich Web experience with jQuery, Ajax and .NETA Rich Web experience with jQuery, Ajax and .NET
A Rich Web experience with jQuery, Ajax and .NETJames Johnson
 
Jquery plugin development
Jquery plugin developmentJquery plugin development
Jquery plugin developmentFaruk Hossen
 

Similar to Cleaner, Leaner, Meaner: Refactoring your jQuery (20)

The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Organizing Code with JavascriptMVC
Organizing Code with JavascriptMVCOrganizing Code with JavascriptMVC
Organizing Code with JavascriptMVC
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
jQuery Loves You
jQuery Loves YoujQuery Loves You
jQuery Loves You
 
jQuery - Tips And Tricks
jQuery - Tips And TricksjQuery - Tips And Tricks
jQuery - Tips And Tricks
 
jQuery's Secrets
jQuery's SecretsjQuery's Secrets
jQuery's Secrets
 
Jquery optimization-tips
Jquery optimization-tipsJquery optimization-tips
Jquery optimization-tips
 
jQuery Anti-Patterns for Performance
jQuery Anti-Patterns for PerformancejQuery Anti-Patterns for Performance
jQuery Anti-Patterns for Performance
 
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 JavascriptjQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
 
jQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't KnowjQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't Know
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
A Rich Web experience with jQuery, Ajax and .NET
A Rich Web experience with jQuery, Ajax and .NETA Rich Web experience with jQuery, Ajax and .NET
A Rich Web experience with jQuery, Ajax and .NET
 
jQuery
jQueryjQuery
jQuery
 
How te bring common UI patterns to ADF
How te bring common UI patterns to ADFHow te bring common UI patterns to ADF
How te bring common UI patterns to ADF
 
Jquery examples
Jquery examplesJquery examples
Jquery examples
 
Jquery plugin development
Jquery plugin developmentJquery plugin development
Jquery plugin development
 

More from Rebecca Murphey

Getting Started with Mulberry
Getting Started with MulberryGetting Started with Mulberry
Getting Started with MulberryRebecca Murphey
 
DojoConf: Building Large Apps
DojoConf: Building Large AppsDojoConf: Building Large Apps
DojoConf: Building Large AppsRebecca Murphey
 
Lessons from-a-rewrite-gotham
Lessons from-a-rewrite-gothamLessons from-a-rewrite-gotham
Lessons from-a-rewrite-gothamRebecca Murphey
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeRebecca Murphey
 

More from Rebecca Murphey (8)

Getting Started with Mulberry
Getting Started with MulberryGetting Started with Mulberry
Getting Started with Mulberry
 
Introducing Mulberry
Introducing MulberryIntroducing Mulberry
Introducing Mulberry
 
DojoConf: Building Large Apps
DojoConf: Building Large AppsDojoConf: Building Large Apps
DojoConf: Building Large Apps
 
Lessons from-a-rewrite-gotham
Lessons from-a-rewrite-gothamLessons from-a-rewrite-gotham
Lessons from-a-rewrite-gotham
 
Lessons from a Rewrite
Lessons from a RewriteLessons from a Rewrite
Lessons from a Rewrite
 
Modern JavaScript
Modern JavaScriptModern JavaScript
Modern JavaScript
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
 
Jquery Fundamentals
Jquery FundamentalsJquery Fundamentals
Jquery Fundamentals
 

Recently uploaded

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 

Recently uploaded (20)

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 

Cleaner, Leaner, Meaner: Refactoring your jQuery

  • 1. Cleaner, Leaner, Meaner Refactoring your JavaScript Rebecca Murphey • @rmurphey • rebeccamurphey.com Thursday, December 2, 2010
  • 2. http://github.com/rmurphey/refactor-jquery 2 Thursday, December 2, 2010
  • 3. “... changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.” Martin Fowler, “Refactoring” 3 Thursday, December 2, 2010
  • 4. Why Refactor? Hint: Not just because it’s fun. Thursday, December 2, 2010
  • 5. “When you sit down and solve a problem, that solution is merely a rst draft.” Stoyan Stefanov, “JavaScript Patterns” 5 Thursday, December 2, 2010
  • 6. Internal rewards Increase maintainability Increase extensibility & reusability User experience rewards Improve page performance Increase testability (reduce bugs) 6 Thursday, December 2, 2010
  • 7. Put another way: Refactoring will make your users happier, make your code cheaper to work with, or both. 7 Thursday, December 2, 2010
  • 8. JavaScript Code Smells 8 tell-tale signs your code needs some TLC Thursday, December 2, 2010
  • 9. $('#showMessage').click(function() { $('<div>' + '<h1>' + $('#messageTitle').val() + '</h1>' + '<p>' + $('#messageText').val() + '</p>' + '</div>') .appendTo('#messageContainer') }); // MINTY FRESH: Use templates instead <script type="text/x-jquery-tmpl" id="messageTemplate"> <div> <h1>${title}</h1> <p>${text}</p> </div> </script> $('#messageTemplate').template('messageTemplate'); $.tmpl('messageTemplate', { title : $('#messageTitle').val(), text : $('#messageText').val() }) .appendTo('#messageContainer'); HTML in your JavaScript 9 Thursday, December 2, 2010
  • 10. http://api.jquery.com/category/plugins/templates/ http://github.com/janl/mustache.js/ http://documentcloud.github.com/underscore/ 10 Thursday, December 2, 2010
  • 11. $('p.special').click(function() { $(this).css({ 'color' : 'red', 'font-weight' : 'bold' }); }) // MINTY FRESH: Keep presentation information in CSS p.extraSpecial { color: red; font-weight: bold; } $('p.special').click(function() { $(this).addClass('extraSpecial'); }); Changing style information in JavaScript 11 Thursday, December 2, 2010
  • 12. function isItemInArray(item, arr) { var inArray = false, len = arr.length; for (var i = 0; i < len; i++) { if (item == arr[i]) { inArray = true; } } return inArray; } // MINTY FRESH: Use jQuery! function isItemInArray(item, arr) { return $.inArray(item, arr) > -1; } Duplication of existing jQuery methods 12 Thursday, December 2, 2010
  • 13. http://api.jquery.com/category/utilities/ http://api.jquery.com/category/miscellaneous/ 13 Thursday, December 2, 2010
  • 14. $('a.thinger').each(function() { $(this).attr('href', $(this).attr('href') + '?ajax=true'); }); $('a.thinger').hide(); $('#myButton').click(function(){ $('a.thinger').show(); }) // MINTY FRESH: Use the chain and setter functions! var thingers = $('a.thinger'), // store selection in a var button = $('#myButton'); // just in case! thingers.attr('href', function(idx, oldVal) { // pass a setter function & avoid the need // to iterate over matches return oldVal + '?ajax=true'; }).hide(); button.click(function() { thingers.show(); }); Repetition that jQuery lets you avoid 14 Thursday, December 2, 2010
  • 15. $(document).ready(function() { $('#enableAwesome').click(function() { $('ul.foo li').each(function() { var li = $(this); li.data('name', li.html()) .find('a.remove').click(function(e) { $.ajax({ url : $(this).attr('href'), dataType : 'json', type : 'post', success : function(resp) { if (resp.ok) { li.remove(); } }, error : console.log }) e.preventDefault(); }); }) }); }); Deeply nested anonymous functions 15 Thursday, December 2, 2010
  • 16. // MINTY FRESH: Isolate functionality into an object with methods var awesome = { enableListItem : function() { var li = $(this); li.data('name', li.html()); }, removeListItem : function() { var a = $(this), li = a.closest('li'); awesome.removeOnServer({ url : a.attr('href'), success : function(resp) { if (resp.ok) { li.remove(); } } }); }, removeOnServer : function (config) { var defaults = { type : 'post', dataType : 'json', error : console.log }, settings = $.extend({}, defaults, config); if (!settings.url) { return; } $.ajax(config); } }; 16 Thursday, December 2, 2010
  • 17. $(document).ready(function() { $('#enableAwesome').click(function() { $('ul.foo li') .each(awesome.enableListItem) .delegate('a.remove', 'click', awesome.removeListItem); }); }); 17 Thursday, December 2, 2010
  • 18. // SMELLY: Overtesting for truthiness if (errorMsg != null && errorMsg.length > 0) { // ... } // MINTY FRESH: Be as terse as you can if (errorMsg && errorMsg.length) { // ... } Overtesting for truthiness 18 Thursday, December 2, 2010
  • 19. // SMELLY if (total == null || total == "0") { // ... } // MINTY FRESH if (!parseInt(total, 10)) { // ... } 19 Thursday, December 2, 2010
  • 20. // SMELLY if (price == null) { // ... } else if(discountPrice != null && price == discountPrice) { // ... } // MINTY FRESH if (!price) { // ... // we already know that price isn't null, // so why test if discountPrice is? if it's // equal to price, we know it's not null } else if (price == discountPrice) { // ... } 20 Thursday, December 2, 2010
  • 21. function isItABigNumber(num) { if(num > 5000) { $('#myContainer').html('<p>It was a big number</p>'); $('#myInput').val(num); $('.thinger').hide(); } else { $('#myContainer').html('<p>It was not a big number</p>'); $('#myInput').val(''); $('.thinger').show(); } } // MINTY FRESH: Only repeat what needs repeating function isItABigNumber(num) { var big = num > 5000; $('#myContainer').html(big ? '<p>It was a big number</p>' : '<p>It was not a big number</p>'); $('#myInput').val(big ? num : ''); $('.thinger')[big ? 'hide' : 'show'](); } Repetitive logic blocks 21 Thursday, December 2, 2010
  • 22. function crazyConcatenation(selector, word1, word2, word3, repeat) { var arr = [], words = [], joinedWords; if (selector == null) { return; } if (word1 == null) { return; } if (word2 != null) { words.push(word2); } if (word3 != null) { words.push(word3); } if (!repeat) { repeat = 5; } joinedWords = words.join(', '); while (repeat--) { arr.push(joinedWords); } $(selector).html(arr.join('<br/>')) } crazyConcatenation('#foo', 'Hello', null, null, 5); Passing a lot of arguments to a function 22 Thursday, December 2, 2010
  • 23. // MINTY FRESH: Using an object instead function crazyConcatenation(config) { // indicate clearly what's required if ( !config.selector || !config.words || !config.words.length ) { return; } var defaults = { repeat : 5 }, settings = $.extend({}, defaults, config), joinedWords = settings.words.join(', '); while (settings.repeat--) { arr.push(joinedWords); } $(settings.selector).html(arr.join('<br/>')) } crazyConcatenation({ selector : '#foo', words : [ 'foo', 'bar', 'baz' ], repeat : 20 }); 23 Thursday, December 2, 2010
  • 24. Advanced Moves Common patterns for improving your code Thursday, December 2, 2010
  • 25. “Writing to be read means writing code ... with the idea that someone else will read it. is fact alone will make you edit and think of better ways to solve the problem you have at hand.” Stoyan Stefanov, “JavaScript Patterns” 25 Thursday, December 2, 2010
  • 26. example add the same behavior to similar content without depending on IDs 26 Thursday, December 2, 2010
  • 27. example cache XHR responses, and create an API to a server-side service 27 Thursday, December 2, 2010
  • 28. example refactor a portlet to use the jQuery UI widget factory 28 Thursday, December 2, 2010
  • 29. rebeccamurphey.com blog.rebeccamurphey.com @rmurphey http://github.com/rmurphey/refactor-jquery http://pinboard.in/u:rmurphey/t:refactor/ Presented at the 2010 Rich Web Experience 29 Thursday, December 2, 2010