Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Underscore.js Grows OOP-Syntax Sugar (Have Your Cake and Eat it Too)
39 points by jashkenas on Nov 9, 2009 | hide | past | favorite | 6 comments
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:

     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();
     
     => {lumberjack : 2, all : 4, night : 2 ... }

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.

The Array prototype methods are proxied through the chained object, so you can slip in a "reverse" or a "concat" without breaking your chain.

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.




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.


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


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.


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!


'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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: