在Javascript中制作函数的真实副本

我想在 Javascript 中定义两个函数(或类),它们具有完全相同的函数体,但它们是完全不同的对象。用例是我在主体中有一些通用逻辑,它是多态的(函数可以接受多种类型),但是通过只调用具有单一类型的函数,函数最终会更快,我假设因为 JIT 可以在每种情况下都采取更快乐的快速路径。

一种方法是简单地完全重复函数体:

function func1(x) { /* some body */ }
function func2(x) { /* some body */ }

另一种以较少重复完成相同事情的方法是eval()

function func(x) { /* some body */ }
function factory() { return eval("(" + func.toString() + ")") }
let func1 = factory(), func2 = factory()

eval()当然,缺点是任何其他工具(缩小器、优化器等)都完全出乎意料,并且有可能破坏我的代码,因此这不起作用。

在标准工具链(我使用 Typescript、esbuild 和 Vite)的范围内,是否有任何明智的方法可以做到这一点,而不使用技巧eval()或只是复制粘贴代码?我也有关于类定义的类似问题。


编辑:总结评论中发生的事情:

  1. 是的,性能差异是真实且可衡量的(尤其是在 Chrome 上,在 Firefox 和 Safari 上不那么明显),正如这个微基准所证明的那样。引发这个问题的真实程序要大得多,性能差异也更明显,我怀疑是因为 JIT 可以为单态函数做更多的内联,这会产生许多连锁反应。
  2. 返回闭包的明显解决方案不起作用,即
    function factory() { function func() { /* some body */ } return func }
    let func1 = factory(), func2 = factory()
    

    正如第二个微基准所证明的那样。这是因为 JIT 只会编译一个函数体一次,即使它是一个闭包。

  3. 这可能已经是最好的解决方案,至少在标准 JS/Typescript 工具链(不包括代码生成或宏工具)中工作时如此。
以上是在Javascript中制作函数的真实副本的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>