为什么在使用Function构造函数进行动态代码求值时没有形成闭包
Why are closures not formed while doing dynamic code evaluation using the Function constructor?
那么,在动态代码评估的两种方法(Function constructor
和eval()
)中,前者不创建闭包,而后者创建闭包?为什么在使用Function
构造函数评估某些代码时不形成闭包?ECMA规范是否规定了这种行为?
ECMA规范是否规定了这种行为?
是的。第15.3.2.1节描述了评估new Function
时执行的算法。注意最后一步:
11.返回按照13.2中的指定创建的新Function对象,将p作为FormalParameterList,将body作为FunctionBody。在全局环境中作为Scope参数传入,并将strict作为strict标志传入。
函数将在其中运行的作用域是全局作用域,而不是进行调用的当前作用域,因此它不能形成闭包。
另一方面,通过eval
执行的代码在当前范围内运行(§10.4.2):
b。将LexicalEnvironment设置为与调用执行上下文的LexicalEnvironment相同的值
c.将VariableEnvironment设置为与调用执行上下文的VariableEnvironment相同的值。
这里有一种查看函数和eval
影响闭包的方法。
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
在当前作用域中工作,而函数是作为全局作用域中的函数调用的。
但实际上,请尽量避免使用任何一种。
相关文章:
- 如何在Angularjs中重构闭包中的重复代码
- 使用Google闭包编译器调试代码删除
- 以下代码片段是命名空间还是闭包
- @internal react 代码中的 JavaScript 文档标签,是 jsdoc、闭包还是其他什么
- 闭包编译器将't关闭可疑代码警告
- 使用闭包编译器简单优化从函数内部删除调试代码
- 使用闭包编译器编写更好的面向对象JavaScript完整示例代码
- Node.js:异步代码 + js 闭包的问题
- 使用闭包编译器缩小包含 Jinja2 表达式的 JavaScript 代码
- 闭包编译器缩小代码中 (0, obj.method)(param1, param2) 的目的
- 如何在代码中使用闭包
- 为什么在使用Function构造函数进行动态代码求值时没有形成闭包
- 如何告诉闭包编译器忽略代码
- 尝试理解一些与JS中的闭包相关的代码
- 为什么我应该考虑在代码中使用JavaScript闭包
- Google闭包编译器不会移除带有@define注释的不可访问代码
- 获取周围的JS闭包代码作为文本
- 是否可以将匿名函数标记为“实时代码”?这样闭包编译器就不会删除它
- 为什么我有两个不同的结果,当我执行这个javascript闭包代码
- 在JavaScript中调用闭包时,是在输入闭包代码时创建的新执行上下文