[AttributeName(Params)] [AttributeName(Params), AttributeName(Params)] public void Foo() { … }
AOP( [AttributeName(Params)], [AttributeName(Params) , AttributeName(Params)], function Foo() { … } );
function AOP() { var advices = []; // for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; // , , // if (Object.prototype.toString.call( arg ) === "[object Array]") { for (var j = 0, advice = arg[j]; j < arg.length; j++) { advices.push(advice); } } else { if (typeof arg === "function") { name = getFunctionName(arg); // // .. for (var j = 0; j < advices.length; j++) { var advice = advices[j]; arg = advice.apply(arg); } // , // , // . . // FunctionName window[name] = arg; } // advices.length = 0; } } } function getFunctionName(fn) { var source = fn.toString(); var head = source.split("(")[0]; var fnName = head.split(" ")[1]; return fnName; }
function Advice(implementation) { this.implementation = implementation; } // fn - Advice.prototype.apply = function(fn) { if (typeof fn !== "function") { throw "You can apply an advice only to a function"; } // return this.implementation(fn); }
function OnBeforeAdvice(onBeforeHandler) { return new Advice(function(fn) { return function() { onBeforeHandler(fn, arguments); return fn.apply(this, arguments); } }); } function OnAfterAdvice(onAfterHandler) { return new Advice(function(fn) { return function() { var result = fn.apply(this, arguments); onAfterHandler(fn, arguments, result); return result; } }); } function OnErrorAdvice(onErrorHandler) { return new Advice(function(fn) { return function() { try { return fn.apply(this, arguments); } catch (e) { onErrorHandler(fn, arguments, e); } } }); } // // "Pet.prototype.getName" function FunctionName(fnName) { return new Advice(function(fn) { var root = window, objs = fnName.split("."), i, oName; for (i = 0; i < objs.length - 1; i++) { oName = objs[i]; if (!root.oName) { root[oName] = {}; } root = root[oName]; } oName = objs[i]; root[oName] = fn; return fn; }); }
<script type="text/javascript"> AOP( [OnBeforeAdvice(onBeforeHandler)], [OnAfterAdvice(onAfterHandler)], function sqr(x) { return x * x; }, [OnAfterAdvice(onBeforeHandler)], [FunctionName("AliasA")], function A() { }, [OnErrorAdvice(onErrorHandler)], function throwsException() { throw "Exception"; } ); function onBeforeHandler(fn, args) { console.log("I know that somebody calls " + fn.toString().split("(")[0]); } function onAfterHandler(fn, args, result) { console.log("Returns " + result + " from " + args[0]); } function onErrorHandler(fn, args, e) { console.log(e + " was thrown"); } onload = function () { sqr(10); A(); AliasA(); throwsException(); } </script>
Source: https://habr.com/ru/post/145539/
All Articles