Your SlideShare is downloading. ×
0
Cleaner, Leaner, Meaner            Refactoring your JavaScript            Rebecca Murphey • @rmurphey • rebeccamurphey.com...
http://slideshare.net/rmurphey/refactor-jquery               http://github.com/rmurphey/refactor-jquery                   ...
“... changing a software system in such a way              that it does not alter the external behavior              of th...
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 ...
Internal rewards               Increase maintainability               Increase extensibility & reusability               U...
Put another way: Refactoring will make your               users happier, make your code cheaper to work               with...
JavaScript                             Code Smells                             8 tell-tale signs your code needs some TLCT...
$(#showMessage).click(function() {                        $(<div> +                          <h1> + $(#messageTitle).val()...
http://api.jquery.com/category/plugins/templates/               http://github.com/janl/mustache.js/               http://d...
$(p.special).click(function() {                         $(this).css({                           color : red,              ...
function isItemInArray(item, arr) {                        var inArray = false,                            len = arr.lengt...
http://api.jquery.com/category/utilities/               http://api.jquery.com/category/miscellaneous/                     ...
$(a.thinger).each(function() {                         $(this).attr(href, $(this).attr(href) + ?ajax=true);               ...
$(document).ready(function() {                        $(#enableAwesome).click(function() {                          $(ul.f...
// MINTY FRESH: Isolate functionality into an object with methods                      var awesome = {                    ...
$(document).ready(function() {                        $(#enableAwesome).click(function() {                          $(ul.f...
// SMELLY: Overtesting for truthiness                      if (errorMsg != null && errorMsg.length > 0) {                 ...
// SMELLY                      if (total == null || total == "0") {                        // ...                      }  ...
// SMELLY                      if (price == null) {                        // ...                      } else if(discountP...
function isItABigNumber(num) {                        if(num > 5000) {                          $(#myContainer).html(<p>It...
function crazyConcatenation(selector, word1, word2, word3, repeat) {                        var arr = [],                 ...
// MINTY FRESH: Using an object instead                      function crazyConcatenation(config) {                        ...
Advanced Moves               Common patterns for improving your codeThursday, December 2, 2010
“Writing to be read means writing code ... with               the idea that someone else will read it. is               f...
example add the same behavior to similar               content without depending on IDs                                   ...
example cache XHR responses, and create an               API to a server-side service                                     ...
example refactor a portlet                             to use the jQuery UI widget                             factory    ...
rebeccamurphey.com                             blog.rebeccamurphey.com                             @rmurphey              ...
Upcoming SlideShare
Loading in...5
×

Cleaner, Leaner, Meaner: Refactoring your jQuery

10,590

Published on

Published in: Technology
2 Comments
22 Likes
Statistics
Notes
  • Good stuff, Rebecca - I was looking for tips on refactoring jQuery-heavy javascript, and your presentation helped me get off of dead center.

    jQuery is an excellent aid for rapid prototyping, but when I use it that way, I often end up with a bowl of spaghetti. Round 1 is getting it to work, round 2 is making it readable and maintainable, and you helped me out with round 2.

    Thanks!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • I love these slides! Did you know we’re running a competition on SlideShare to win a 3M PocketProjector MP180? To enter, simply tag your presentation with ‘3MInform’. Head over to our page for more details... and don’t forget to follow us to find out if you get shortlisted!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
10,590
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
169
Comments
2
Likes
22
Embeds 0
No embeds

No notes for slide

Transcript of "Cleaner, Leaner, Meaner: Refactoring your jQuery"

  1. 1. Cleaner, Leaner, Meaner Refactoring your JavaScript Rebecca Murphey • @rmurphey • rebeccamurphey.comThursday, December 2, 2010
  2. 2. http://slideshare.net/rmurphey/refactor-jquery http://github.com/rmurphey/refactor-jquery 2Thursday, December 2, 2010
  3. 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” 3Thursday, December 2, 2010
  4. 4. Why Refactor? Hint: Not just because it’s fun.Thursday, December 2, 2010
  5. 5. “When you sit down and solve a problem, that solution is merely a rst draft.” Stoyan Stefanov, “JavaScript Patterns” 5Thursday, December 2, 2010
  6. 6. Internal rewards Increase maintainability Increase extensibility & reusability User experience rewards Improve page performance Increase testability (reduce bugs) 6Thursday, December 2, 2010
  7. 7. Put another way: Refactoring will make your users happier, make your code cheaper to work with, or both. 7Thursday, December 2, 2010
  8. 8. JavaScript Code Smells 8 tell-tale signs your code needs some TLCThursday, December 2, 2010
  9. 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 9Thursday, December 2, 2010
  10. 10. http://api.jquery.com/category/plugins/templates/ http://github.com/janl/mustache.js/ http://documentcloud.github.com/underscore/ 10Thursday, December 2, 2010
  11. 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 11Thursday, December 2, 2010
  12. 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 12Thursday, December 2, 2010
  13. 13. http://api.jquery.com/category/utilities/ http://api.jquery.com/category/miscellaneous/ 13Thursday, December 2, 2010
  14. 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 14Thursday, December 2, 2010
  15. 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 15Thursday, December 2, 2010
  16. 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); } }; 16Thursday, December 2, 2010
  17. 17. $(document).ready(function() { $(#enableAwesome).click(function() { $(ul.foo li) .each(awesome.enableListItem) .delegate(a.remove, click, awesome.removeListItem); }); }); 17Thursday, December 2, 2010
  18. 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 18Thursday, December 2, 2010
  19. 19. // SMELLY if (total == null || total == "0") { // ... } // MINTY FRESH if (!parseInt(total, 10)) { // ... } 19Thursday, December 2, 2010
  20. 20. // SMELLY if (price == null) { // ... } else if(discountPrice != null && price == discountPrice) { // ... } // MINTY FRESH if (!price) { // ... // we already know that price isnt null, // so why test if discountPrice is? if its // equal to price, we know its not null } else if (price == discountPrice) { // ... } 20Thursday, December 2, 2010
  21. 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 21Thursday, December 2, 2010
  22. 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 22Thursday, December 2, 2010
  23. 23. // MINTY FRESH: Using an object instead function crazyConcatenation(config) { // indicate clearly whats 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 }); 23Thursday, December 2, 2010
  24. 24. Advanced Moves Common patterns for improving your codeThursday, December 2, 2010
  25. 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” 25Thursday, December 2, 2010
  26. 26. example add the same behavior to similar content without depending on IDs 26Thursday, December 2, 2010
  27. 27. example cache XHR responses, and create an API to a server-side service 27Thursday, December 2, 2010
  28. 28. example refactor a portlet to use the jQuery UI widget factory 28Thursday, December 2, 2010
  29. 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 29Thursday, December 2, 2010
  1. A particular slide catching your eye?

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

×