Function构造函数的合法使用 [英] Legitimate uses of the Function constructor
问题描述
正如反复说的那样,使用函数构造函数<被认为是不好的做法/ a>(另请参阅 ECMAScript语言规范,5 th edition,§15.3.2.1):
As repeatedly said, it is considered bad practice to use the Function constructor (also see the ECMAScript Language Specification, 5th edition, § 15.3.2.1):
new Function ([arg1[, arg2[, … argN]],] functionBody)
(其中所有参数都是包含参数名称和最后一个的字符串(或者只有)字符串包含函数体。)
(where all arguments are strings containing argument names and the last (or only) string contains the function body).
重新概括,据说它很慢,如 Opera团队:
To recapitulate, it is said to be slow, as explained by the Opera team:
每次[...]
函数
构造函数在字符串
上调用源代码,脚本
引擎必须启动
将源代码转换为可执行
代码的机制。这对于
的性能来说通常很昂贵 - 例如,比简单的函数
调用便宜一百倍
。 (Mark'Tarquin'Wilton-Jones)
Each time […] the
Function
constructor is called on a string representing source code, the script engine must start the machinery that converts the source code to executable code. This is usually expensive for performance – easily a hundred times more expensive than a simple function call, for example. (Mark ‘Tarquin’ Wilton-Jones)
根据 =https://developer.mozilla.org/Talk:En/Core_JavaScript_1.5_Reference/Functions_and_function_scope#new_Function%28%29_vs_function%28%29.7.7d =nofollow noreferrer>这篇文章关于MDC (虽然我没有使用当前版本的Firefox测试这个。)
Though it's not that bad, according to this post on MDC (I didn't test this myself using the current version of Firefox, though).
Crockford 添加
Crockford adds that
[t]他引用
的约定语言使
非常难以正确表达函数体作为
字符串。在字符串形式中,早期的
错误检查无法完成。 [...]并且
浪费内存,因为每个
函数需要自己独立的
实现。
[t]he quoting conventions of the language make it very difficult to correctly express a function body as a string. In the string form, early error checking cannot be done. […] And it is wasteful of memory because each function requires its own independent implementation.
另一个区别是
Another difference is that
由函数
构造函数定义的函数不会继承任何范围
其他比全局范围(所有
函数都继承)。 ( MDC )
除此之外,当您创建新函数
使用动态内容。
Apart from this, you have to be attentive to avoid injection of malicious code, when you create a new Function
using dynamic contents.
那就是说,TJ Crowder在答案中说
That said, T.J. Crowder says in an answer that
[t]这里几乎从不需要
类似的新函数(...),
,除了一些先进的
边缘情况。
[t]here's almost never any need for the similar […] new Function(...), either, again except for some advanced edge cases.
所以,现在我想知道:这些高级边缘情况是什么? 是否合法使用了Function构造函数?
So, now I am wondering: what are these "advanced edge cases"? Are there legitimate uses of the Function constructor?
推荐答案
NWMatcher - Javascript CSS选择器和匹配器,作者:Diego Perini - 使用函数
构造函数(< a href =http://github.com/dperini/nwmatcher/blob/master/src/nwmatcher.js#L910 =nofollow noreferrer> 1 , 2 , 3 , 4 等)创建(编译)选择器匹配器的高效版本。
NWMatcher — Javascript CSS selector and matcher, by Diego Perini — uses Function
constructor (1, 2, 3, 4, etc.) to create ("compile") highly-efficient versions of selector matchers.
基准(我刚刚在Chrome 5上运行)说明了一切:
The benchmark (which I just ran on Chrome 5) speaks for itself:
注意NWMatcher和Sizzle之间的区别,这是一个非常相似的选择器引擎,只有没有函数编译:)
Note the difference between NWMatcher and Sizzle, which is a very similar selector engine, only without function compilation :)
注意,ECMAScript 5 在调用函数
时不会抛出任何错误。无论是严格的还是标准的模式。但是,严格模式对标识符的存在几乎没有限制,例如eval和arguments:
On a side note, ECMAScript 5 doesn't throw any errors on invocation of Function
. Neither in strict, nor in "standard" modes. Strict mode, however, introduces few restrictions on presence of identifiers such as "eval" and "arguments":
-
你可以'使用这样的名称声明变量/函数/参数:
You can't have declare variables/functions/arguments with such names:
function eval() { }
var eval = { };
function f(eval) { }
var o = { set f(eval){ } };
您无法分配到此类标识符:
You can't assign to such identifier:
eval = { };
另请注意,在严格模式下, eval
语义与ES3略有不同。严格模式代码无法在调用它的环境中实例化变量或函数:
Also note that in strict mode, eval
semantics is slightly different from that in ES3. Strict mode code can not instantiate variables or functions in the environment from which it was called:
eval(' "use strict"; var x = 1; ');
typeof x; // "undefined"
这篇关于Function构造函数的合法使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!