

Underscore.js Grows OOP-Syntax Sugar (Have Your Cake and Eat it Too) - jashkenas

This morning, Underscore.js went to version 0.4.2. As a brief reintroduction, Underscore is a library of functional helper methods that fits in neatly alongside jQuery. It now has an option to use OO-style syntax, as well as sequences of chained operations on collections. Here's an example of chaining in action:<p><pre><code>     var lyrics = [
       {line : 1, words : "I'm a lumberjack and I'm okay"},
       {line : 2, words : "I sleep all night and I work all day"},
       {line : 3, words : "He's a lumberjack and he's okay"},
       {line : 4, words : "He sleeps all night and he works all day"}
     ];

     _(lyrics).chain()
       .map(function(line) { return line.words.split(' '); })
       .flatten()
       .reduce({}, function(counts, word) {
         counts[word] = (counts[word] || 0) + 1;
         return counts;
     }).value();
     
     =&#62; {lumberjack : 2, all : 4, night : 2 ... }

</code></pre>
The library has benefitted immensely from the opinions gathered on Hacker News from an earlier posting, and I wanted to see what y'all think of this addition.<p>The Array prototype methods are proxied through the chained object, so you can slip in a "reverse" or a "concat" without breaking your chain.<p>Finally, some speed comparisons with jQuery have been added to the bottom of the testing and benchmark page. Because Underscore proxies to the browser-native implementation, doing an "each()" on a thousand-element array is over 5 times faster than the jQuery equivalent in Safari, and over 3.5 times faster in Firefox. Your mileage may vary, so you can use that page to run your own tests in your favorite browser.
======
jashkenas
Clickable Links

Underscore.js: <http://documentcloud.github.com/underscore>

Speed Tests: <http://documentcloud.github.com/underscore/test/test.html>

Development Code: <http://documentcloud.github.com/underscore/underscore.js>

Minified Code (2k gzipped, fits on a screen):
<http://documentcloud.github.com/underscore/underscore-min.js>

------
futuremint
When I read 'OO-style' sadly I immediately thought of sugar to create private
variables/methods and some lame class-based inheritance (which I strongly
advocate is nigh useless in JS).

Now I understand you mean 'OO-style' in the message passing / Smalltalk sense
of the phrase. Which is much better IMHO, but might be lost on monolingual
practitioners using "broken" OO style in their languages.

------
fortes
Nice work. Have you considered offering your speed improvements as a patch to
jQuery?

~~~
jashkenas
Sure, there's not much there to offer. Underscore just delegates to the native
implementations of "map", "forEach", "reduce", "reduceRight", "filter",
"some", "every", and so on...

I bet that jQuery would do the same if they could, but their arguments are
incompatible with the native versions -- instead of passing in each element as
the first argument to the iterator, jQuery binds the element to "this" for
each pass through the iterator. In addition, you can return false from a
jQuery loop to break out of the iteration, something that's not supported by
the native forEach, and that wouldn't work for "map", in any case. Changing
any of this would be a major, backwards-incompatible change...

For what it's worth, in Google's Closure Library, they delegate in the same
fashion. See "goog.array.forEach", etc.

------
mdrcode
Is there a feed? (Or do you have a blog independent of the project?)

Awesome work, I'd love to keep tabs via rss if possible!

~~~
jashkenas
'Fraid not, for the moment. Large announcements will be made on the
DocumentCloud.org blog, but that covers a bunch of other stuff.

Your best bet for keeping pace with development is probably to follow the
project on GitHub.

