Tuesday, April 29, 2014

Defining Functions With RequireJS

JavaScript is a functional language, where functions are first-class citizens. Sometimes, rather than trying to encapsulate all behaviour inside one object or another, it's easier to just define the function. Something I've found myself doing is defining an object whose only purpose is to hold references to my utility functions. So, other modules in my code will require this utility object, that has several functions attached to it, and may only use one of them. So why not define widely-used functions as AMD modules?

For example, here's what the scaffolding of my utility object might look like.

define(function() {

    return {
        hasPerm: function( user, perm ) {},
        isAdmin: function( user ) {}
    };

});

One problem I have with this approach is that it's badly-named. Something called "util" is bound to collect garbage. Have to implement something in a hurry? Put it in util — just temporarily. The other issue I have with this approach is that this module returns an object that's already instantiated, and it it really shouldn't be an object in the first place. There's no state encapsulated within — it's just generic helper functions that apply throughout our application. So, why not define them as such?

define(function() {

    return (function hasPerm( user, perm ) {
        return true;
    });

});

When I require the hasPerm module, I know exactly what I'm getting. I can import the hasPerm() function, on it's own, into other modules. No need for an added level of indirection.