0

那么在动态代码评估(Function constructorvs eval())的两种方式中,前一种不会创建闭包,而后一种会?Function为什么在使用构造函数评估某些代码时没有形成闭包?这种行为是 ECMA 规范规定的吗?

4

2 回答 2

3

这种行为是 ECMA 规范规定的吗?

这是。第 15.3.2.1 节new Function描述了在评估时执行的算法。注意最后一步:

11. 返回一个按照13.2中指定的方法创建的新 Function 对象,将P作为FormalParameterList并将 body 作为FunctionBody。将Global Environment作为Scope参数传入,并将strict作为Strict标志。

函数将运行的范围是全局范围,而不是进行调用的当前范围,因此它不能形成闭包。

另一方面,通过eval执行的代码在当前范围内运行(第 10.4.2 节):

湾。将 LexicalEnvironment 设置为与调用执行上下文的LexicalEnvironment相同的值。
C。将 VariableEnvironment 设置为与调用执行上下文的 VariableEnvironment 相同的值。

于 2013-08-03T13:52:49.603 回答
2

这是一种查看Functioneval.

var z = 0;
(function () {                                 // Local    | Global
    var x = 0, y = 0;                          // x  y  z  | x      y      z
    console.log(x, y, z);                      // 0  0  0  |
    console.log(window.x, window.y, window.z); //          | undef  undef  0
    new Function('var x = 1; y = 1; z = 1')(); // Function set 1
    console.log(x, y, z);                      // 0  0  1  |
    console.log(window.x, window.y, window.z); //          | undef  1      1
    eval('var x = 2; y = 2; z = 2');           // Eval set 2
    console.log(x, y, z);                      // 2  2  2  |
    console.log(window.x, window.y, window.z); //          | undef  1      2
}());

您可以看到它eval在当前范围内工作,而Function在全局范围内作为函数调用。

但实际上,请尽量避免使用其中任何一个。

于 2013-08-03T13:52:50.820 回答