JS函数构造函数每次重新解析? [英] JS Function-constructor re-parsed everytime?

查看:111
本文介绍了JS函数构造函数每次重新解析?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在MDN中,关于函数和函数范围,每次评估解析是什么意思?这可以通过代码来观察吗?



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


函数表达式和函数声明定义的函数仅被解析一次,而函数构造函数定义的函数不是 STRONG>。也就是说,传递给Function构造函数的函数体字符串在每次评估时都必须被解析。尽管函数表达式每次都会创建一个闭包,但是函数体是 not reparsed ,所以函数表达式比new Function(...)更快。因此,应该尽可能地避免函数构造函数。但是,应该注意的是,函数表达式和函数声明嵌套在函数构造函数的字符串生成的函数中,不会被解析反复即可。例如:

var foo =(new Function(var bar = \''FOO!\'; \ nreturn(function(){\\\\\\\\\\\\\\\\\\\\\\\\\' \\\
});))();
foo(); //函数体字符串中的段function

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

  var bar ='FOO!'; 
var foo =(new Function(return(function(){\\\
\talert(bar); \\\
});))();
吧='FOO!再次';
foo(); //函数体字符串的段function(){\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

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

两者都提醒again-version。



重新包装是指什么?



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



谢谢。




仅供参考,我试过另一个代码片段:

  var bar ='FOO!'; 
var string1 =return(function(){\\\
\talert(bar); \\\
});;
var foo =(new Function(string1))();
吧='FOO!再次';
foo(); //函数体字符串的段function(){\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
string1 =return(function(){\\\
\talert(bar +'more'); \\\
});;
foo();

两次都会提示FOO!, 不是 strong>FOO!again more。

解决方案

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



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

$ p $ function makeAlerterParse(string){
return Function(alert(+ JSON .stringify(字符串)+ ););

函数makeAlerterClosure(字符串){
返回函数alerter(){alert(string); };
}

当脚本加载时,这两个函数声明都会被解析 - 没有什么意外。但是,在闭包中, alerter 函数表达式已被解析。让我们来做一些提醒:

  var alerter1 = makeAlerterParser(1); //这里解析器将被调用
alerter1(); //没有解析,函数已经实例化并且
alerter1(); //可以被一次又一次地解释。

var alerter2 = makeAlerterClosure(2); //这里,没有解析器调用 -
alerter2(); //它只是一个代码已知的闭包
alerter2(); //但现在有一个包含2字符串的特殊作用域

好,那么你已经明白了一切。这个警告只是一个明确的调用,例如(/ var fnarr = [],i = 0; i <100; i ++ )
fnarr [i] = makeAlerterParse(i);

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


In MDN, about Functions and function scope, what does it mean by parsed every time it is evaluated? Can this be observed by codes?

Quote in the section Function constructor vs. function declaration vs. function expression:

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});"))();
foo(); //The segment "function() {\n\talert(bar);\n}" of the function body string is not re-parsed.

I have written a code snippet to (try to) test and understand it:

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

Both two alerts the "again-version".

What does it mean by reparsed or not?

Can this be illustrated by code results?

Thanks.


FYI, i have tried another code snippet:

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

Both alerts "FOO! again", not "FOO! again more".

解决方案

What they wanted to highlight is that the JS parser needs to its work every single time the Function constructor is called - basically just the obvious. There is no caching of the passed code string involved.

This is relevant [only] when compared with closures. Suppose we have these two functions:

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

Both function declarations will be parsed when the script is loaded - no surprises. However, in the closure also the alerter function expression is parsed already. Let's make some alerters:

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

Still no surprise? Good, then you have already understood everything. The warning is only that an explicit invocation like

for (var fnarr=[], i=0; i<100; i++)
    fnarr[i] = makeAlerterParse(i);

will really be 100 invocations of the JS parser, while the closure version comes for free.

这篇关于JS函数构造函数每次重新解析?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆