[javascript]
すべての投稿/コメントを注意深く読んだ後、OPはとを探していると思います[method-modification]
。そして、用語に関するOPの質問にすぐに答えると、JavaScriptで閉じた機能を変更することは、 AOであると主張する実装が少なくともアスペクト、アドバイス、ポイントカットの抽象化とコード再利用レベルを提供しない限り、アスペクト指向プログラミングとは何の関係もありません。
Scott Sauyetがすでにコメント
しているように、他のすべては、機能を互いに(手動で)ラップするだけで実行できます。ここでも、私はそれほど遠くまでは行かず、それをfunction-compositionと呼びます。compose
その資格を得るには、さまざまな実装やcurry
メソッド/パターンがすでに存在するため、少なくともいくつかのツールセットが必要です。
OPが達成しようとしていることについてはbefore
、多くの解決策がありafter
around
ますが、ほとんどの場合、残念ながらAO(P)wrap
に言及しており、多くの場合、コンテキストに注意を払っていないか、これは不可欠であり、OPからも求められています。 。target
私が提供する例では、のプロトタイプ実装を使用していますFunction.around
。JavaScriptはすでに標準化された機能を備えているので、、、、、
など の他のメソッド修飾子にも適切な場所で
ある
と
bind
確信して
い ます。Function.prototype
before
after
around
afterThrowing
afterFinally
後で次の例をサポートするコードベース:
(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.around = function (handler, target) { // [around]
target = getSanitizedTarget(target);
var proceed = this;
return (isFunction(handler) && isFunction(proceed) && function () {
return handler.call(target, proceed, handler, arguments);
}) || proceed;
};
}(Function));
サンプルコード、その前後に追加で提供された動作によって特定の閉関数を変更し、そのコンテキストも提供します。
var loggingDelegate = function () { // closed code that can not be changed for any reason.
this.log.apply(this, arguments);
};
loggingDelegate.call(console, "log", "some", "arguments");
var interceptedLoggingDelegate = loggingDelegate.around(function (proceed, interceptor, args) {
// everything that needs to be done before proceeding with the intercepted functionality.
// [this] in this example refers to [console], the second argument of the [around] modifier.
this.log("proceed:", proceed); // the original functionality - here [loggingDelegate].
this.log("interceptor:", interceptor); // the modifying functionality - [around]s 1st argument.
this.log("args:", args); // the arguments that get passed around.
proceed.apply(this, args);
// or:
//return proceed.apply(this, args);
// or:
//var result = proceed.apply(this, args);
// everything that still needs to be done after invoking the intercepted functionality.
// if necessary:
//return result;
}, console); // [console] has to be provided as target to the modified [loggingDelegate].
interceptedLoggingDelegate("intercept", "and", "log", "some", "arguments");