Tutorial — Intercept Essentials
Part 2 of a Guide to Function Interception in JavaScript
Contents
Applying Prefixes
Applying prefixes (and suffixes and wrappers) requires just a single call to either AspectJS object, and Example Two illustrates the essential principle. Here the code sets a prefix on a function called MyFunc, and then calls MyFunc, the result being that Prefix is executed first, after which MyFunc is executed.
Examining the arguments that are passed to AddPrefix:
The first parameter indicates what object the interceptee is a member of (the interceptee owner). In the example, MyFunc is a global function, and is therefore a member of the Global object. 'this' is therefore quoted, because AddPrefix has been called at global scope. However, were MyFunc a member of another object, then the name of that object would form the second parameter. Note that, when setting an intercept on a global function from within a method of another object, the this reference will point to that other object (unless 'this' has been changed by calling the method using call or apply). In those cases 'window' should be passed to the AspectJS function in question ('window' being an alias for the Global object).
The second parameter indicates the function that is to be intercepted (the interceptee). This must be in quotes.
The third parameter indicates which function should serve as the prefix to MyFunc. Note that this is not in quotes, as the argument must be a reference to a function rather than to a string.

 // Example 2

 function Prefix ()
    {
    alert ("Prefix executed");
    }

 function MyFunc ()
    {
    alert ("MyFunc executed");
    }


 AJS.AddPrefix (this, "MyFunc", Prefix);

 MyFunc ();

 --------------------------------------

 Output:

 Prefix executed
 MyFunc executed
            
Note also that JavaScript's evaluation model means that a call to AddPrefix does not have to come after definition of, or calls to, the intercepted function - it antecedes the function definitions here for reasons of clarity alone.
Similarly, note that it is not necessary for the call to AddPrefix to reside in the same source file as the call to MyFunc — the two can be related very distantly, in terms of a given code-base, as long as the call to AddPrefix precedes the relevant call to MyFunc at run-time (in the above example).
Applying Suffixes
Applying suffixes is the complement of applying prefixes and, requires only a change to the AspectJS method that is called, and the diagram illustrates the execution path when a suffixed interceptee is called.
Given this, Example Three demonstrates the necessary syntax. Here a call to MyFunc causes that procedure to execute first, after which the suffix is executed. Aside from that, the meaning of the arguments passed to AddSuffix is identical to those passed to AddPrefix; although do note that the full calling-signature available to suffix functions is more sophisticated than that available to prefixes.

 // Example 3

 function Suffix () { alert ("Suffix executed"); }
 function MyFunc () { alert ("MyFunc executed"); }


 AJS.AddSuffix (this, "MyFunc", Suffix);

 MyFunc ();

 --------------------------------------

 Output:

 MyFunc executed
 Suffix executed
            
Passing Arguments to Interceptees
Arguments can be passed to an intercepted function in the usual (non-intercepted) fashion. These pass through the interception mechanism transparently, and Example Four illustrates this.

 // Example 4

 function Prefix () { alert ("Prefix executed"); }

 function MyFunc (Value)
     {
     alert ("MyFunc executed. Argument passed = " + Value);

     }


 AJS.AddPrefix (this, "MyFunc", Prefix);

 MyFunc (10);

 --------------------------------------

 Output:

 Prefix executed
 MyFunc executed. Argument passed = 10
            
Returning Results from Interceptees
Interceptees can return values to their callers in the same way as any other function; and the value object passes back up through the interception mechanism transparently, as one would expect. Example Five illustrates this.

 // Example 5

 function Prefix () { alert ("Prefix executed"); }

 function MyFunc (Value)
     {
     alert ("MyFunc executed");

     return 10;

     }


 AJS.AddPrefix (this, "MyFunc", Prefix);

 var Value = MyFunc ();

 alert ("Function Returned - Value  = " + Value);

 --------------------------------------

 Output:

 Prefix executed
 MyFunc executed
 Function Returned - Value = 10
            
Interceptees and Exceptions
Exception handling is equally transparent as passing arguments and returning results, meaning that exceptions that arise from executing the interceptee pass up through the interception mechanism and can be caught in the usual manner.
Example Six illustrates catching an exception thrown from within an intercepted function.

 // Example 6

 function Prefix () { alert ("Prefix executed"); }

 function MyFunc (Value)
     {
     alert ("MyFunc executed, throwing exception...");

     throw new Error ("MyFunc Exception");

     }


 AJS.AddPrefix (this, "MyFunc", Prefix);

 try { MyFunc (); }
 catch (E)
    {
    alert ("Exception caught - Message contents = " + E.message);

    }

 --------------------------------------

 Output:

 Prefix executed
 MyFunc executed, throwing exception...
 Exception caught - Message contents = MyFunc Exception
            
Note that, if a function has a suffix, and the function throws an exception, the suffix will not be executed, as Example Seven illustrates.

 // Example 7

 function Suffix () { alert ("Suffix executed"); }

 function MyFunc (Value)
     {
     alert ("MyFunc executed, throwing exception...");

     throw new Error ("MyFunc Exception");

     }


 AJS.AddSuffix (this, "MyFunc", Suffix);

 try { MyFunc (); }
 catch (E)
    {
    alert ("Exception caught - Message contents = " + E.message);

    }

 --------------------------------------

 Output:

 MyFunc executed, throwing exception...
 Exception caught - Message contents = MyFunc Exception;
            
Note also that exceptions that are thrown by prefixes and suffixes are caught by the intercept mechanism, and do not propagate up to the interceptee's caller.
In Example Eight, invocation of MyFunc causes Prefix to execute, which throws an exception. This escapes Prefix's scope, but propagates no further, and MyFunc executes as normal.

 // Example 8

 function Prefix ()
    {
    alert           ("Prefix executed, throwing exception...");
    throw new Error ("Prefix Exception");
    }

 function MyFunc () { alert ("MyFunc executed"); }


 AJS.AddPrefix (this, "MyFunc", Prefix);

 try { MyFunc (); }
 catch (E)
    {
    alert ("Exception caught - Message contents = " + E.message);

    }

 --------------------------------------

 Output:

 Prefix executed, throwing exception...
 MyFunc executed
            
Go forward to Part 3 of this tutorial.
Go back to Part 1 of this tutorial.
Copyright © Dodeca Technologies Ltd. 2007