Based on dotvoid solution, I created my own version of JS AOP for my own projects needs. I basically want to minimize the aspect setup costs, so I added aspect setup functionality at Function.prototype.

Function.prototype.applyBefore = function (aspect, targetFuncNames) { .... }

I also need to support aync callbacks, such as supporting authentication and authorization for certain methods. For example:

var authenticateAspect = function (error, success, context, args) { logger.log('authenticate (applyBefore async) aspect is being called'); var request = $.ajax({ url: "http://localhost/BlogWeb/api/user/authenticate", type: "GET", data: { username:'jeff', pwd:'jeff' }, success: function (data) { if (data) { success(); } else { error(); } }, error: error }); return request; }; Person.applyBefore(authenticateAspect, 'sendNotification'); var p1 = new Person(); p1.sendNotification();

To implement this, I need to run the security and and continue upon success or stop execution on failure.

var invalidAspect = new Error("Missing a valid aspect. Aspect is not a function."), invalidMethod = new Error("Missing valid method to apply aspect on."); ///Parameters: aspect - defines the methods we want call before or/and /// after each method call ob target obejct /// targetFuncNames - target function names to apply aspects ///Return: it should return a new object with all aspects setup on target object Function.prototype.applyBefore = function (aspect, targetFuncNames) { if (typeof (aspect) != 'function') throw invalidAspect; if (typeof (targetFuncNames) != 'object') targetFuncNames = Array(targetFuncNames); var targetObj = this; //error handling function // Copy the properties over onto the new prototype for (var i = 0, len = targetFuncNames.length; i < len; i++) { var funcName = targetFuncNames[i]; var targetFunc = targetObj.prototype[funcName]; if (!targetFunc) throw invalidMethod; targetObj.prototype[funcName] = function () { var self = this, args = arguments; var success = function() { return targetFunc.apply(self, args); }; var error = function () { logger.log('applyBefore aspect failed to pass'); //log the error and throw new error throw new Error('applyBefore aspect failed to pass'); }; var aspectResult = aspect.apply(null, Array.prototype.concat([error, success, self], args)); return aspectResult; }; } };

Full implementation can be found at http://www.jeffjin.net/aop-with-javascript