在 MDN 中,关于功能及功能范围 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope#Function_constructor_vs._function_declaration_vs._function_expression,这是什么意思每次评估时都会解析?这可以通过代码观察吗?
引用部分函数构造函数、函数声明、函数表达式:
由函数表达式和函数声明定义的函数是仅解析一次,而那些由 Function 构造函数定义的are not。也就是说,传递给 Function 构造函数的函数体字符串必须是每次评估时都会解析。虽然函数表达式每次都会创建一个闭包,但函数体是没有重新解析,因此函数表达式仍然比“new Function(...)”更快。因此,应尽可能避免使用 Function 构造函数。
但是,应该注意的是,函数表达式和函数声明嵌套在通过解析 Function 构造函数的字符串生成的函数中不被重复解析。例如:
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.
我编写了一个代码片段来(尝试)测试并理解它:
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();
两者都提醒“再次版本”。
这是什么意思reparsed or not?
可以通过代码结果来说明吗?
Thanks.
仅供参考,我尝试了另一个代码片段:
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!再次”警报,not“FOO!又来了”。
他们想要强调的是,JS 解析器每次都需要工作。Function
构造函数被调用——基本上就是显而易见的。不涉及对传递的代码字符串的缓存。
这[仅]与闭包相比才相关。假设我们有这两个函数:
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 次,而闭包版本是免费的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)