Decorators in JavaScript

A decorator is a function which takes a function and returns a function:

decorator = (fn) -> fn

Obviously, this doesn't do anything useful. It's the fact that a decorator can return a function which behaves similarly to the function passed to it that makes the pattern interesting. Commonly a decorator will simply wrap a function invocation in a check of some sort:

var loginRequired = function (fn) {
  return function () {
    if (!user.authenticated) {
      return window.location.replace('/login');
    }
    fn.apply(null, [].slice.apply(arguments));
  };
};

The above decorator could be used to "guard" actions that only authenticated users are permitted to perform:

var changeUsername = loginRequired(function (username) {
  $.ajax({
    type: 'PUT',
    url: '/api/1.0/users/' + user.id,
    data: {username: username}
  })});

var changePassword = loginRequired(function (password) {
  $.ajax({
    type: 'PUT',
    url: '/api/1.0/users/' + user.id,
    data: {password: password}
  })});

var deleteAccount = loginRequired(function () {
  $.ajax({
    type: 'DELETE',
    url: '/api/1.0/users/' + user.id
  })});

The CoffeeScript equivalent is quite a bit clearer:

changeUsername = loginRequired (username) ->
  $.ajax
    type: 'PUT'
    url: "/api/1.0/users/#{user.id}"
    data: {username}

changePassword = loginRequired (password) ->
  $.ajax
    type: 'PUT'
    url: "/api/1.0/users/#{user.id}"
    data: {password}

deleteAccount = loginRequired ->
  $.ajax
    type: 'DELETE'
    url: "/api/1.0/users/#{user.id}"

Decorators are commonly used in Python — which provides special syntax for "decorating" functions — but are rarely seen in JavaScript code. This despite the fact that JavaScript's first-class functions are ideally suited to the task. Perhaps CoffeeScript's lighter-weight function syntax will result in decorators making more frequent appearances in JavaScript code.

Respond