我还将给出一个较晚的答案,以便对这种特殊情况有所了解,这种情况时不时地以JavaScript 和 AOP的形式出现。
首先,像 OP 提出的这种情况总是要求修改已经存在的功能,从而针对封闭的代码,这些代码有时甚至不属于认为自己因修改此类代码的控制流而受到挑战的一方。
那么,为什么不只是这样命名... JavaScript 方法修改或JavaScript 方法修饰符。
其次,由于已经骑着术语,改变 JavaScript 中的封闭功能与面向切面编程无关,除非声称是AO的实现至少为Aspect、Advice和Pointcut提供抽象和代码重用级别。
最后,对于 OP 将要实现的目标以及公认的答案,确实存在一大堆before
, after
around
/wrap
解决方案,不幸的是几乎总是提到AO(P),并且在太多情况下没有考虑到上下文或target
对方法修改至关重要。
我提供的示例使用afterThrowing
. 由于bind
JavaScript
已经具有标准化
的. Function.prototype
_ _ _before
after
around
afterThrowing
afterFinally
// OP's example pseudo code
//
// functionName.before("try {")
//
// functionName.after("} catch(ex){
// dostuff
// }")
function doStuffAfterThrowing(exception, originalArguments) {
"use strict";
var context = this;
console.log('context : ', context);
console.log('String(exception) : ', String(exception));
console.log('originalArguments : ', originalArguments);
return "safely handled exception";
}
function doFail() {
throw (new ReferenceError);
}
function oneOutOfManyAjaxCallbacks(payload) {
doFail();
}
var jsonData = {
"foo": "foo",
"bar": "bar"
};
var someModifiedAjaxCallback = oneOutOfManyAjaxCallbacks.afterThrowing(doStuffAfterThrowing, { x: 'y' });
// does fail controlled/handled.
console.log('someModifiedAjaxCallback(jsonData) : ', someModifiedAjaxCallback(jsonData));
// does fail "Uncaught".
console.log('oneOutOfManyAjaxCallbacks(jsonData) : ', oneOutOfManyAjaxCallbacks(jsonData));
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>
(function (Function) {
var
isFunction = function (type) {
return (
(typeof type == "function")
&& (typeof type.call == "function")
&& (typeof type.apply == "function")
);
},
getSanitizedTarget = function (target) {
return ((target != null) && target) || null;
}
;
Function.prototype.afterThrowing = function (handler, target) { // afterThrowing
target = getSanitizedTarget(target);
var proceed = this ;
return (isFunction(handler) && isFunction(proceed) && function () {
var ret, args = arguments;
try {
ret = proceed.apply(target, args);
} catch (exc) {
ret = handler.call(target, exc, args);
//throw exc;
}
return ret;
}) || proceed;
};
}(Function));
</script>
走到这一步,人们也可以考虑阅读......