Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用AOP调用方法前后的Javascript控制台输出_Javascript_Aop_Sapui5_Function Composition_Modifier - Fatal编程技术网

使用AOP调用方法前后的Javascript控制台输出

使用AOP调用方法前后的Javascript控制台输出,javascript,aop,sapui5,function-composition,modifier,Javascript,Aop,Sapui5,Function Composition,Modifier,我想测量方法的计算时间 一个好方法是()与console.time('Function#1')和控制台.timeEnd('Function#1') 我的想法是在生命周期方法上添加这些控制台输出。在本例中,使用类似SAPUI5的createContent:funtion(){}方法 这应该可以通过AOP使用before()和after()来运行时间计数 您会建议哪种AOP框架,以及如何实现它,同时需要自动修改标识字符串“Function#1”?实际上不需要Javascript中的方面,因为您可以随

我想测量方法的计算时间

一个好方法是()与
console.time('Function#1')
控制台.timeEnd('Function#1')

我的想法是在生命周期方法上添加这些控制台输出。在本例中,使用类似SAPUI5的
createContent:funtion(){}方法

这应该可以通过AOP使用
before()
after()
来运行时间计数


您会建议哪种AOP框架,以及如何实现它,同时需要自动修改标识字符串“Function#1”?

实际上不需要Javascript中的方面,因为您可以随时更改任何对象的任何函数。JavaScript原型允许您在运行时操纵对象所有实例的方法实现。这里有两种方法可以实现您的计划

您可以使用通用包装器函数:

var measureId = 0;
var fnMeasureFunction = function(fnToMeasure) {
  console.time('measure'+ measureId);
  fnToMeasure();
  console.timeEnd('measure'+ measureId);
  measureId++;
}
诚然,这要求您更改实际代码

对于静态函数或属于原型的函数,您也可以从外部执行类似操作,而无需对现有代码进行任何更改:

// any static function
var measureId = 0;
var fnOriginalFunction = sap.ui.core.mvc.JSViewRenderer.render;
sap.ui.core.mvc.JSViewRenderer.render = function() {
  console.time('measure'+ measureId);
  fnOriginalFunction.apply(this, arguments);
  console.timeEnd('measure'+ measureId);
  measureId++;
}

// any prototype function
var fnOriginalFunction = sap.m.Button.prototype.ontouchstart;
sap.m.Button.prototype.ontouchstart= function() {
  console.time('measure'+ measureId);
  fnOriginalFunction.apply(this, arguments);
  console.timeEnd('measure'+ measureId);
  measureId++;
}
这应该可以通过AOP使用before()和after()来运行时间计数

正如已经提到的,一个人实际上并不需要真正的面向方面编程 为了解决JavaScript中的此类任务。但这种语言可能需要更标准化一些 除了已经存在的
bind
方法之外,还有方法修饰符

请查看我最近关于这个问题的两篇帖子:

。。。如何在需要自动修改标识字符串“Function#1”的情况下实现它

由于控制台的
time
/
timeEnd
功能只需要 测量时间的相同入口和出口点(如秒表的启动/停止触发器)。 因此,我们可以准确地理解当前正在运行/测量的函数/方法的引用

为了解决给定的任务,我将仅建议在
前后进行
,而不是在
之前进行
和
前者的
生成的开销较小。下一个代码块示例性地显示了 可能的原型实现。它也是下面示例的基础 这最终可能解决OP的任务

(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));
下一个示例考虑了方法修改基本上依赖于 绑定到对象的功能。这不仅仅是功能包装。整齐 为了不丢失方法正在操作的上下文,必须委托上下文/ 在所有操作中作为
target
传递

因此,该示例不修改
计算
,因为它未绑定到对象 但它改为修改触发器

var testObject={
计算:函数(hugeInteger){
变量
i=hugeInteger,
k=0
;
而(我--){
k++;
}
返回k;
},
触发器:函数(hugeInteger){
this.result=this.calculate(hugeInteger);
},
结果:-1
};
log(“testObject.result:”,testObject.result);
log(“testObject.trigger(Math.pow(2,26)):”,testObject.trigger(Math.pow(2,26));//需要一些时间。
log(“testObject.result:”,testObject.result);
console.log(“testObject.someTrigger(0):”,testObject.trigger(0));//之后立即记录日志。
log(“testObject.result:”,testObject.result);
testObject.trigger=testObject.trigger.around(函数(继续、拦截器、args){
//之前:
控制台。时间(继续);
//进行:
继续。应用(本,args);
//之后:
控制台。时间结束(继续);
},testObject);//省略第二个参数[target]对象可能会破坏以前可以工作的代码。
log(“testObject.trigger(Math.pow(2,26)):”,testObject.trigger(Math.pow(2,26));
log(“testObject.result:”,testObject.result)
.as控制台包装{最小高度:100%!重要;顶部:0;}

(功能(功能){
变量
isFunction=函数(类型){
返回(
(typeof type==“函数”)
&&(typeof type.call==“函数”)
&&(typeof type.apply==“函数”)
);
},
getSanitizedTarget=函数(目标){
返回((target!=null)&&target)| null;
}
;
Function.prototype.around=函数(处理程序,目标){/[around]
目标=getSanitizedTarget(目标);
var继续=这个;
返回(isFunction(处理程序)和isFunction(继续)和函数(){
调用(目标、继续、处理程序、参数);
})| |继续;
};
}(功能);