在MDN中,关于Functions and function scope,每次对求值时解析的是什么意思?可以通过代码遵守吗?

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



我已经编写了一个代码片段来(尝试)测试并理解它:

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();

两者都警告“再次版本”。

是否重新解析是什么意思?

代码结果可以说明吗?

谢谢。

仅供引用,我尝试了另一个代码段:
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);

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

07-24 18:36
查看更多