使用“new Function”和性能问题

Use of `new Function` and performance issues

本文关键字:性能 问题 Function new 使用      更新时间:2023-09-26

我正在通过AJAX加载一个脚本文件,并运行其内容,我这样做:

new Function('someargument',xhr.responseText)(somevalue);
然而,根据MDN:
Function构造函数创建的

Function对象在创建函数时进行解析。这比声明一个函数并在代码中调用它效率低,因为用function语句声明的函数要和其余代码一起解析。

我真的不太明白。如果声明了一个函数,它仍然必须从文件的字符串格式解析,那么为什么通过new Function运行加载的字符串效率会更低呢?

这对我来说真的更像是一件好奇的事情。我可以理解为什么它会坏在一个循环(不得不重新解析相同的字符串),但对于这样的东西,我不认为有任何问题,是有吗?

我想他们的意思是,如果你在代码中像这样使用函数构造函数:

new Function('bar', 'console.log(bar);'));

函数体被解析两次:第一次是在加载代码时作为字符串解析,第二次是在运行时构造函数时解析。在您的示例中,您是在解析代码后从ajax响应创建函数的,因此实际上是完全不同的处理。

认为 MDN文档指的是这样的东西:

var f = new Function("return 5;");

相对于:

function f() { return 5; }

前一个版本效率较低,因为它首先在JavaScript中创建一个实际的String对象("return 5"),然后解析该字符串以创建Function对象。后者解析没有中间字符串的代码。

也就是说,在你的情况下,因为你是动态加载JavaScript代码,我不认为真的有任何绕过它

我不知道MDN那篇文章的作者是什么意思,但这里有一个解释。

许多现代JS解释器使用优化编译器来生成本机代码。

例如,"JavaScriptCore, the WebKit JS implementation"说:

在这种情况下,在三种形式之间存在分层编译:初始解析和编译产生字节码,可以使用JIT方法进行优化,可以通过DFG JIT进行优化。在实践中,尽管在大多数平台上没有包含解释器,因此所有代码都通过JIT方法运行。

优化编译器对它正在编译的代码的了解越全面,它可以执行的优化就越多,因此函数的优化程度也就越高。例如,如果您知道函数的每个引用都被用来立即调用它,并以字符串作为唯一参数,因为它是在严格的函数体中定义的,那么您可能完全可以避免为它分配函数对象,并在函数体中执行某些优化。

当您调用new Function时,优化编译器不会获得执行这些优化和其他优化所需的上下文。