ruk·si

⬇️ Underscore.js Tricks

Updated at 2013-11-16 15:24

Underscore is a great library, you should definitely use it for every project that has more than few lines of JavaScript. It helps to eliminate all loops while providing other neat functionality. You should read through every single function on the Underscore website.

In this note, I highlight some of the functions that I find myself using quite frequently that I think might be rarer. All collection related functions in Underscore.js are very useful, you should read them through.

_.defaults() Fill in undefined properties of an object.

var Person = function(options) {
    options = _.defaults(options || {}, {
        name: 'Default Larsson',
        age: 33
    });
};

_.debounce() Runs function only if not called for X milliseconds.

var logSize = function() {
    var h = $(window).height();
    var w = $(window).width();
    console.log('H: ' + h ', W: '+ w);
}
var lazyLayout = _.debounce(logSize, 300);
$(window).resize(lazyLayout);

var Item = Backbone.View.extend({
    render: function() {
        _.debounce(this._render, 200)
    },
    _render: function() {
        // Render...
    }
});

_.defer(), _.delay() Specifies functions to be invoked later when there is time. Essentially cleaner version of setTimeout where you can specify additional parameters to be given to the invoked function.

var log = _.bind(console.log, console);
_.delay(log, 1000, 'logged later');
// => 'logged later' after 1 second.

// Asynchronous rendering for collections so it does not block execution.
var Item = Backbone.View.extend({
    render: function(items) {
        items = items || this.collection.models;
        var toRender = _(items).first(50);
        var toDoLater = _(items).rest(50); // All but first 50.
        _(toRender).each(function() {
            var view = new ItemView(item);
            view.render();
        });
        _.defer(this.render, toDoLater);
    }
});

_.throttle() Forces function to be invoked only once per X milliseconds and stores if function needs to invoked on next timeout.

var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);

_.wrap() Wraps a function inside another function. Easy to change the function signature, execute code before the function or execute code after the function.

var hello = function(name) {
    return "hello: " + name;
};
var wrappa = function(func) {
    return "before, " + func("moe") + ", after";
}
hello = _.wrap(hello, wrappa);
hello();
// => 'before, hello: moe, after'

_().times() Invokes the given function X times.

_(3).times(function(n) { console.log('Whoo! Round ' + n + '!'); });

_.random() Gives random integer between two integers.

_.random(0, 100);

_.escape(),_.unescape() HTML escaping.

_.escape('Curly, Larry & Moe');
_.unescape('Curly, Larry & Moe');

_.result() Finds a named property of the given object. (a) if non-function, return it or (b) if function, invoke and return the result.

var myObj = {
    cheese: 'crumpets',
    stuff: function() {
        return 'nonsense';
    }
};
_.result(myObj, 'cheese'); // => 'crumpets'
_.result(myObj, 'stuff'); // => 'nonsense'

Sources