将类方法作为参数与参数一起传递

Passing class methods as parameters, together with arguments

提问人:Levent 提问时间:3/4/2023 更新时间:3/4/2023 访问量:56

问:

我正在编写一个处理大量随机性的程序,并且我正在实现自动化测试,以测量函数的单个运行时间。

我有一个定义多个函数的类,我希望编写一个函数,该函数将使用给定的输入 X 次测试其中一个函数并返回总运行时间。然后,我将使用我的类定义的每个函数的随机输入来调用此函数,并打印结果。我的类写得如下:

class myClass {
    constructor(a) { ... }
    fun1(a) { ... }
    fun2(a, b) { ... }
    static randomInstance { ... } // Returns a random instance of myClass
    // etc.
}

我测试这一点的代码如下:

 function timeFunction(fun, params, it) { 
   let t0, t1; 
   let total = 0;  
   for (let i = 1; i <= it; i++) { 
     let rand = myClass.randomInstance(); 
     t0 = performance.now(); 
     rand.fun.apply(this, params); // I also tried fun(params)
     t1 = performance.now(); 
     total += t1-t0; 
   } 
   return total; 
 }

最后,我根据函数的参数(许多函数共享同一组参数)和时间来分离函数:

function myClassTest(it=50) {
  // Divide functions into different arrays depending on parameters 
  aInputFunctions = ['fun1'];
  abInputFunctions = ['fun2'];
  

  let a = ...;
  let b = ...;
  for (const fun of aInputFunctions) {
    const time = timeFunction(fun, [a], it);
    print(it + ' iterations of ' + fun + ' took ' + time + ' milliseconds.');
    print('\t Average duration of a single run: ' + time/it + '.\n');
  }
  for (const fun of abInputFunctions) {
    const time = timeFunction(fun, [a, b], it);
    print(it + ' iterations of ' + fun + ' took ' + time + ' milliseconds.');
    print('\t Average duration of a single run: ' + time/it + '.\n');
  }
}

但是,这不能正确运行。当我(在 Node 上)运行它时,我收到一个错误:

rand.fun.apply(这个,参数); TypeError:无法读取 undefined 的属性(读取“apply”)

我怎样才能让它工作?关于将函数作为参数传递,我在这里遗漏了什么?我发现了很多关于传递函数的指南,但关于传递类函数的指南并不多,因为谁在 JS 中做 OOP,对吧?

并且必须有一种更好的方法来进行随机单元测试,但我有一个(相对)简单的用例,而且我不是JS专家(显然)。

JavaScript 函数 参数传递

评论

1赞 mrall 3/4/2023
rand[fun].apply(this,params) 因为 aInputFunctions 将函数的名称存储为字符串,而不是函数本身。
0赞 Levent 3/4/2023
这似乎大部分奏效了,谢谢!当有问题的函数不带参数时,我应该将什么作为参数传递?我以为传递一个空数组就可以解决问题,但事实并非如此。
0赞 mrall 3/10/2023
您也可以只执行 rand[fun].apply(rand),而不必传递第二个参数。

答:

1赞 Bergi 3/4/2023 #1

由于是字符串,而不是函数,因此不能使用 .此外,您不能使用 ,因为这将调用名为“fun”的方法,而不使用变量。funfun()rand.fun()fun

你想要的是

rand[fun].apply(rand, params);

rand[fun](...params);

评论

0赞 Levent 3/5/2023
这回答了我的问题,谢谢!当函数不接受参数时,将空数组作为参数传递似乎不起作用,但文档建议我应该改为传递 null。我会尽快测试一下。
1赞 Bergi 3/6/2023
@Levent 空数组绝对应该有效
0赞 Levent 3/8/2023
我发现空数组有问题。我(错误地)实现了 Python 样式的默认值;我定义了函数 fun1(a=1)...。但是,传递空数组后,将参数 a 初始化为 null 而不是默认值 1。
1赞 Bergi 3/8/2023
不应该吗?只有当数组包含 时,才会发生这种情况。如果数组包含值 (即 ) 或为空 (nullundefined[undefined][])
0赞 Levent 3/8/2023
是的,所以我读过,但奇怪的是没有。也许我应该就此提出另一个问题,但有趣的是,我可以毫无问题地直接调用函数,但是此方法以某种方式更改了默认参数,从而导致运行时错误。