質問
どのJavaScript AOPライブラリを使用しますか。また、その主な機能は何ですか?
解決
これまで私が見つけたものは次のとおりです。
- dotvoid の実装、きれいな構文、使用するのが良い、この記事は与えられたコードを使用する理由/方法についての良い紹介であり、紹介をサポートしていますが、バグがあります
- Dojoには、 dojox に優れた組み込み実装と思われるものがあります、こちらは、使用するには、
- jQuery用のプラグイン jquery-aop があり、構文はより粗い、javascriptオブジェクトでオブジェクトとメソッドを渡す、
- AspectJS の構文がさらに粗い(ポイントカットのタイプを引数として渡す必要がある)単一のメソッド)
私が言ったように、dotvoidのコードは機能しませんでした。 私は少し修正し、よりよく機能するように見えるものを得ました:
InvalidAspect = new Error("Missing a valid aspect. Aspect is not a function.");
InvalidObject = new Error("Missing valid object or an array of valid objects.");
InvalidMethod = new Error("Missing valid method to apply aspect on.");
function doBefore(beforeFunc,func){
return function(){
beforeFunc.apply(this,arguments);
return func.apply(this,arguments);
};
}
function doAfter(func, afterFunc){
return function(){
var res = func.apply(this,arguments);
afterFunc.apply(this,arguments);
return res;
};
}
Aspects = function(){};
Aspects.prototype={
_addIntroduction : function(intro, obj){
for (var m in intro.prototype) {
obj.prototype[m] = intro.prototype[m];
}
},
addIntroduction : function(aspect, objs){
var oType = typeof(objs);
if (typeof(aspect) != 'function')
throw(InvalidAspect);
if (oType == 'function'){
this._addIntroduction(aspect, objs);
}
else if (oType == 'object'){
for (var n = 0; n < objs.length; n++){
this._addIntroduction(aspect, objs[n]);
}
}
else{
throw InvalidObject;
}
},
addBefore : function(aspect, obj, funcs){
var fType = typeof(funcs);
if (typeof(aspect) != 'function')
throw(InvalidAspect);
if (fType != 'object')
funcs = Array(funcs);
for (var n = 0; n < funcs.length; n++){
var fName = funcs[n];
var old = obj.prototype[fName];
if (!old)
throw InvalidMethod;
var res = doBefore(aspect,old)
obj.prototype[fName] = res;
}
},
addAfter : function(aspect, obj, funcs) {
if (typeof(aspect) != 'function')
throw InvalidAspect;
if (typeof(funcs) != 'object')
funcs = Array(funcs);
for (var n = 0; n < funcs.length; n++)
{
var fName = funcs[n];
var old = obj.prototype[fName];
if (!old)
throw InvalidMethod;
var res = doAfter(old,aspect);
obj.prototype[fName] = res;
}
},
addAround : function(aspect, obj, funcs){
if (typeof(aspect) != 'function')
throw InvalidAspect;
if (typeof(funcs) != 'object')
funcs = Array(funcs);
for (var n = 0; n < funcs.length; n++)
{
var fName = funcs[n];
var old = obj.prototype[fName];
if (!old)
throw InvalidMethod;
var res = aspect(old);
obj.prototype[fName] = res;
}
return true;
}
}
他のヒント
meld.js
と aop.js
をご覧になりましたか
https://github.com/cujojs ?
SpringSourceは、高度なJavascriptプログラマ向けのその他の便利な機能に加えて、AOP機能を提供します。
免責事項:私はSpringSourceで働いています。
dotvoidソリューションに基づいて、自分のプロジェクトのニーズに合わせてJS AOPの独自バージョンを作成しました。 基本的にアスペクト設定のコストを最小限に抑えたいので、アスペクト設定機能を追加しました Function.prototype。
Function.prototype.applyBefore = function (aspect, targetFuncNames) {
....
}
また、特定のメソッドの認証と承認のサポートなど、ayncコールバックをサポートする必要があります。 例:
var authenticateAspect = function (error, success, context, args) {
logger.log('authenticate (applyBefore async) aspect is being called');
var request = $.ajax({
url: "http://localhost/BlogWeb/api/user/authenticate",
type: "GET",
data: { username:'jeff', pwd:'jeff' },
success: function (data) {
if (data) {
success();
} else {
error();
}
},
error: error
});
return request;
};
Person.applyBefore(authenticateAspect, 'sendNotification');
var p1 = new Person();
p1.sendNotification();
これを実装するには、セキュリティを実行し、成功したら続行するか、失敗したら実行を停止する必要があります。
var invalidAspect = new Error("Missing a valid aspect. Aspect is not a function."),
invalidMethod = new Error("Missing valid method to apply aspect on.");
///Parameters: aspect - defines the methods we want call before or/and
/// after each method call ob target obejct
/// targetFuncNames - target function names to apply aspects
///Return: it should return a new object with all aspects setup on target object
Function.prototype.applyBefore = function (aspect, targetFuncNames) {
if (typeof (aspect) != 'function')
throw invalidAspect;
if (typeof (targetFuncNames) != 'object')
targetFuncNames = Array(targetFuncNames);
var targetObj = this;
//error handling function
// Copy the properties over onto the new prototype
for (var i = 0, len = targetFuncNames.length; i < len; i++) {
var funcName = targetFuncNames[i];
var targetFunc = targetObj.prototype[funcName];
if (!targetFunc)
throw invalidMethod;
targetObj.prototype[funcName] = function () {
var self = this, args = arguments;
var success = function() {
return targetFunc.apply(self, args);
};
var error = function () {
logger.log('applyBefore aspect failed to pass');
//log the error and throw new error
throw new Error('applyBefore aspect failed to pass');
};
var aspectResult = aspect.apply(null, Array.prototype.concat([error, success, self], args));
return aspectResult;
};
}
};
所属していません StackOverflow