Silver's Simple Site - Weblog - Tags - JavaScript


Mixing jQuery and Underscore.js nicely

Working on a new project, with both jQuery and Underscore.js, I found myself with a problem. Using Underscore.js on jQuery objects felt somewhat dirty/messy:

    // With $ and _ both in scope...
   
   // Typical code:
   _($('.someclass'))
       .each(function(element) {
           element = $(element);
           // Run some jQuery on 'element'.
       });
   
   _.chain($('.someclass'))
       .filter(function(element) {
           element = $(element);
           // Test some jQuery on 'element'.
       })
       .each(function(element) {
           element = $(element);
           // Run some jQuery on 'element'.
       });

The two key problems I had were:

  1. The initial "_($('..." and "_.chain($('..." bugged my sense of clean code.
  2. I had to re-wrap every element in jQuery inside each filter() or each() or any other Underscore.js iterator function.

The solution I found is pretty simple and also in two parts:

  1. Add a new mix-in to Underscore.js: the jQuery $() function.
  2. Use the map() method from Underscore.js directly with jQuery's $() function. (This also meant an increased use of the chain() method.)

    // With $ and _ both in scope...
   
   // One-time set-up:
   _.mixin({$: $});
   
   // Typical code:
   _.chain('.someclass')
       .$()     // This uses jQuery to select the elements matching the selector.
       .map($)  // This uses Underscore.js to wrap every matched element in jQuery.
       .filter(function(element) {
           // Test some jQuery on 'element'.
       })
       .each(function(element) {
           // Run some jQuery on 'element'.
       });

Much cleaner!

Addendum: It was pointed out to me that you can avoid the chain() methods of Underscore.js by replacing that library with Lo-Dash, which has much the same API, but with better performance and more intuitive method chaining (i.e. more like jQuery). Thanks tom!

Permalink | Author: | Tags: JavaScript, jQuery, Underscore.js | Posted: 06:00PM on Thursday, 31 October, 2013 | Comments: 0

Powered by the Content Parser System, copyright 2002 - 2024 James G. Ross.