index.js
function weave(type, advised, advisedFunc, aopProxy) {
    let f, $execute, standalone = false,
        transfer = aopProxy.transfer,
        adviser = aopProxy.adviser;

    if (!advisedFunc) {
        standalone = true;
        $execute = advised;
    } else {
        $execute = advised[advisedFunc].bind(advised);
    }
    aopProxy.advised = $execute;

    switch(type){
        case 'before':
            f = function () {
                let result = adviser.apply(advised, arguments);		    // Invoke the advice.
                result = result && !transfer ? [result] : null;
                return $execute.apply(advised, result || arguments);	// Call the original function.
            };
            break;
        case 'after':
            f = function () {
                let result = $execute.apply(advised, arguments);	// Call the original function and store the result.
                result = result && !transfer ? [result] : null;
                return adviser.apply(advised, result || arguments);				// Invoke the advice.
            };
            break;
        case 'around':
            let invocation = {
                proceed: function () {
                    return this.method.apply(this, this.args);
                }
            };
            f = function () {
                invocation.args = arguments;
                invocation.method = $execute;
                invocation.name = advisedFunc;
                return adviser(invocation);
            };
            break;
        default:
            console.log("AOP Error", "Unsupported advice type:  " + type);
    }

    if (standalone) {
        return (advised = f);
    } else {
        return (advised[advisedFunc] = f);
    }

}
function weave(type, advised, advisedFunc, aopProxy) {
    let f, $execute, standalone = false,
        transfer = aopProxy.transfer,
        adviser = aopProxy.adviser;

    if (!advisedFunc) {
        standalone = true;
        $execute = advised;
    } else {
        $execute = advised[advisedFunc].bind(advised);
    }
    aopProxy.advised = $execute;

    switch(type){
        case 'before':
            f = function () {
                let result = adviser.apply(advised, arguments);		    // Invoke the advice.
                result = result && !transfer ? [result] : null;
                return $execute.apply(advised, result || arguments);	// Call the original function.
            };
            break;
        case 'after':
            f = function () {
                let result = $execute.apply(advised, arguments);	// Call the original function and store the result.
                result = result && !transfer ? [result] : null;
                return adviser.apply(advised, result || arguments);				// Invoke the advice.
            };
            break;
        case 'around':
            let invocation = {
                proceed: function () {
                    return this.method.apply(this, this.args);
                }
            };
            f = function () {
                invocation.args = arguments;
                invocation.method = $execute;
                invocation.name = advisedFunc;
                return adviser(invocation);
            };
            break;
        default:
            console.log("AOP Error", "Unsupported advice type:  " + type);
    }

    if (standalone) {
        return (advised = f);
    } else {
        return (advised[advisedFunc] = f);
    }

}
function weave ( type , advised , advisedFunc , aopProxy ) { let f , $execute , standalone = false , transfer = aopProxy . transfer , adviser = aopProxy . adviser ; if ( ! advisedFunc ) { standalone = true ; $execute = advised ; } else { $execute = advised [ advisedFunc ] . bind ( advised ) ; } aopProxy . advised = $execute ; switch ( type ) { case 'before' : f = function ( ) { let result = adviser . apply ( advised , arguments ) ; // Invoke the advice. result = result && ! transfer ? [ result ] : null ; return $execute . apply ( advised , result || arguments ) ; // Call the original function. } ; break ; case 'after' : f = function ( ) { let result = $execute . apply ( advised , arguments ) ; // Call the original function and store the result. result = result && ! transfer ? [ result ] : null ; return adviser . apply ( advised , result || arguments ) ; // Invoke the advice. } ; break ; case 'around' : let invocation = { proceed : function ( ) { return this . method . apply ( this , this . args ) ; } } ; f = function ( ) { invocation . args = arguments ; invocation . method = $execute ; invocation . name = advisedFunc ; return adviser ( invocation ) ; } ; break ; default : console . log ( "AOP Error" , "Unsupported advice type:  " + type ) ; } if ( standalone ) { return ( advised = f ) ; } else { return ( advised [ advisedFunc ] = f ) ; } }
A simple AOP implementation for JavaScript

@author Philip Ford
A simple AOP implementation for JavaScript