Function构造函数的合法使用

Mar*_*pel 40 javascript function-constructor

正如反复提到的,使用Function构造函数被认为是不好的做法(另见ECMAScript语言规范, 5 版,第15.3.2.1节):

new Function ([arg1[, arg2[, … argN]],] functionBody)
Run Code Online (Sandbox Code Playgroud)

(其中所有参数都是包含参数名称的字符串,最后一个(或唯一)字符串包含函数体).

要概括,它被认为是缓慢的,因为通过解释歌剧院团队:

每次Function 在表示源代码的字符串上调用构造函数时,脚本引擎必须启动将源代码转换为可执行代码的机制.这通常对性能来说很昂贵 - 例如,比简单的函数调用要贵一百倍.(Mark'Tarquin'Wilton-Jones)

虽然它并没有那么糟糕,但根据这篇关于MDC的帖子(我没有使用当前版本的Firefox自己测试).

克罗克福德补充

引用该语言的惯例使得将函数体正确表达为字符串变得非常困难.在字符串形式中,无法进行早期错误检查.[...]它浪费了内存,因为每个函数都需要自己独立的实现.

另一个不同之处在于

由Function构造函数定义的函数不会继承除全局范围(所有函数都继承)之外的任何范围.(MDC)

除此之外,在创建new Function使用动态内容时,您必须注意避免注入恶意代码.

也就是说,TJ Crowder在回答中

除了一些高级边缘情况之外,这里几乎从不需要类似的新函数(...).

所以,现在我想知道:这些"先进边缘案例"是什么?Function构造函数是否合法使用?

kan*_*gax 19

NWMatcher -的Javascript CSS选择和匹配器,由Diego的Perini -使用Function构造(1,2,3,4,等等)来创建( "编译")选择的匹配器的高效的版本.

基准测试(我只是跑在Chrome 5)不言自明:

替代文字

注意NWMatcher和Sizzle之间的区别,这是一个非常相似的选择器引擎,只是没有函数编译 :)

另外,ECMAScript 5 在调用时不会抛出任何错误Function.无论是严格的还是"标准的"模式.但是,严格模式对标识符的存在几乎没有限制,例如"eval"和"arguments":

另请注意,在严格模式下,eval语义与ES3中的语义略有不同.严格模式代码无法在调用它的环境中实例化变量或函数:

 eval(' "use strict"; var x = 1; ');
 typeof x; // "undefined"
Run Code Online (Sandbox Code Playgroud)

  • 我已经更新了源代码参考.但基准已经成为一个死链接. (2认同)

har*_*rpo 9

当JSON解析器对象不可用时,jQuery使用它来解析JSON字符串.似乎对我合法:)

        // Try to use the native JSON parser first
        return window.JSON && window.JSON.parse ?
            window.JSON.parse( data ) :
            (new Function("return " + data))();
Run Code Online (Sandbox Code Playgroud)


Dav*_*nco 7

new Function()在我正在开发的一个Web应用程序中使用构造函数作为内联JS解释器:

function interpret(s) {
  //eval(s); <-- even worse practice
  try {
      var f = new Function(s);
      f();
    }
  catch (err) {
      //graceful error handling in the case of malformed code
  }
}
Run Code Online (Sandbox Code Playgroud)

当我通过AJAX(而不是 iframe)传输内容时,我会继续使用interpret()readyStateChange == 3.这非常有效.

编辑:这是一个明确的案例研究,表明它new Function()明显快于eval().即你应该永远(很少?)使用eval代替new Function().

http://polyfx.com/stuff/bsort.html < - 1000次迭代版本,可能会导致浏览器崩溃

http://polyfx.com/stuff/bsort10.html < - 较短的版本

EVAL是平均几乎8倍new Function().

  • 关于通过`eval`计算代码字符串与通过`Function`构造函数进行比较的"更糟糕的做法"究竟是什么? (5认同)
  • 它运行得更快,更容易理解:http://www.go4expert.com/forums/showthread.php?t = 13979此外,如果需要,更容易在特定范围或闭包中删除`f()`(对于安全原因). (2认同)
  • 用我刚写的案例研究编辑了我的答案.在某些浏览器中,Eval几乎慢了10倍. (2认同)

Pre*_*aul 7

John Resig使用Function构造函数来创建用asp语法编写的客户端模板的"编译"版本. http://ejohn.org/blog/javascript-micro-templating/