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

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
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
 
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
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
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
 

Recently uploaded (20)

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
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
 
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...
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
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
 

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