javascript - JS 函数构造函数每次都重新解析?

标签 javascript performance function parsing function-constructor

在 MDN 中,关于 Functions and function scope , parsed every time it is evaluated 是什么意思?这可以通过代码观察到吗?

引用函数构造函数与函数声明与函数表达式部分:

Functions defined by function expressions and function declarations are parsed only once, while those defined by the Function constructor are not. That is, the function body string passed to the Function constructor must be parsed every time it is evaluated. Although a function expression creates a closure every time, the function body is not reparsed, so function expressions are still faster than "new Function(...)". Therefore the Function constructor should be avoided whenever possible.

It should be noted, however, that function expressions and function declarations nested within the function generated by parsing a Function constructor 's string aren't parsed repeatedly. For example:

var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();<br/> foo(); //The segment "function() {\n\talert(bar);\n}" of the function body string is not re-parsed.

我写了一个代码片段来(尝试)测试和理解它:

var bar = 'FOO!';
var foo = (new Function("return(function() {\n\talert(bar);\n});"))();
bar = 'FOO! again';
foo(); //The segment "function() {\n\talert(bar);\n}" of the function body string is not re-parsed.

var bar2 = 'FOO!2';
var foo2 = function() { alert(bar2); };
bar2 = 'FOO!2 again';
foo2();

两者都提示“again-version”。

reparsed 与否是什么意思?

这可以用代码结果来说明吗?

谢谢。


仅供引用,我尝试了另一个代码片段:

var bar = 'FOO!';
var string1 = "return(function() {\n\talert(bar);\n});";
var foo = (new Function(string1))();
bar = 'FOO! again';
foo(); //The segment "function() {\n\talert(bar);\n}" of the function body string is not re-parsed.
string1 = "return(function() {\n\talert(bar + ' more');\n});";
foo();

两个警报“FOO!又来了”,不是“FOO!又来了”。

最佳答案

他们想要强调的是,每次调用 Function 构造函数时,JS 解析器都需要工作——基本上是显而易见的。没有缓存所涉及的传递的代码字符串。

与闭包相比,这 [仅] 是相关的。假设我们有这两个函数:

function makeAlerterParse(string) {
    return Function("alert("+JSON.stringify(string)+");");
}
function makeAlerterClosure(string) {
    return function alerter() { alert(string); };
}

这两个函数声明都将在加载脚本时被解析——这并不奇怪。但是,在闭包中,alerter 函数表达式也已被解析。让我们制作一些警报器:

var alerter1 = makeAlerterParser("1"); // Here the parser will be invoked
alerter1(); // no parsing, the function is instantiated already and 
alerter1(); // can be interpreted again and again.

var alerter2 = makeAlerterClosure("2"); // Here, no parser invocation -
alerter2(); // it's just a closure whose code was already known
alerter2(); // but that has now a special scope containing the "2" string

还是不惊喜?好,那么你已经明白了一切。警告只是像

这样的显式调用
for (var fnarr=[], i=0; i<100; i++)
    fnarr[i] = makeAlerterParse(i);

实际上将调用 100 次 JS 解析器,而闭包版本是免费的。

关于javascript - JS 函数构造函数每次都重新解析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20695573/

相关文章:

javascript - 字符串模板中的三元运算符

javascript - 在 D3 中的 2 个选定节点之间创建手动链接

C++:将 uint 合并和拆分为 4 个字节的最快方法

java - WorkbookFactory.create() 的 Apache Poi 性能问题

c++ - 进程内函数调用的开销

arrays - 如何将函数的所有结果存储到 Lua 中的单个变量中?

javascript - 使用 EasyAutocomplete 的多输入字段 - Rails

JavaScript 视频预告片(包括 YouTube iframe)播放问题,翻页卡正面出现悬停现象

objective-c - 我怎样才能在 Objective-C 中加速这个强力加法算法?

php - 传递 NULL 参数与不传递参数完全相同