Simple Deferred / Promise pattern in JavaScript
A few things caught my eye:


You can call resolve and later call reject too - or the other way around, or call either one multiple times. It should only allow the first resolve/reject call to have an effect.
status might as well be a string (pending, resolved, rejected) which obviate the need for a comment explaining the integer values, and would improve readability
The if(f) check in execute should probably be a full if(typeof f === 'function') check; lots of values are truthy without being functions. You could also do this check in done/fail and simply ignore/complain about non-function arguments.
There's some duplication between done/fail and resolve/reject.


For that last one, if the status becomes a string, it's also relative easy use that as a key for organizing the callbacks and arguments.

function defer() {
  var currentState = 'pending',
      callbacks    = { resolved: [], rejected: [] },
      args         = []; // only need 1 args array

  function execute(state) {
    var cb;
    while(callbacks[state].length) {
      cb = callbacks[state].shift();
      if( typeof cb === 'function' ) cb.apply(this, args);
    }
  }

  // generic function factory for done/fail functions
  function hook(state) {
    return function (cb) {
      callbacks[state].push(cb);
      if(currentState === state) execute(state);
    }
  }

  // generic function factory for resolve/reject functions
  function complete(state) {
    return function () {
      if(currentState !== 'pending') return; 
      args = Array.prototype.slice.call(arguments, 0);
      currentState = state;
      execute(state);
    }
  }

  return {
    promise: function () {
      return { done: hook('resolved'), fail: hook('rejected') };
    },
    resolve: complete('resolved'),
    reject:  complete('rejected')
  };
}


You may want to add then, always and isPending (or just state) functions. And once you've resolved or rejected, you might as well get rid of the callbacks you're not going to ever use (i.e. if resolved, clear out the reject-callbacks,and vice-versa).

Lastly, if you want to emulate jQuery, make it chainable, so you can call x.done(...).fail(...).fail(...).always(...) etc.