我知道JavaScript中的每个函数都是一个第一类对象,它有一个内部属性[[scope]],它承载函数自由变量的绑定记录。但是,有两种特殊情况。
Function构造函数创建的函数是否也是一个闭包? Function构造函数创建的函数对象是特殊的,因为它的[[scope]]可能不引用其外部函数的词法环境,而只引用全局上下文。例如,
var a = 1;
var fn = (function outer() {
var a = 2;
var inner = new Function('alert(a); ');
return inner;
})();
fn(); // will alert 1, not 2.
这是不直观的。这也叫封闭吗?
如果内部函数没有任何自由变量,我们可以说在创建内部函数时会形成闭包吗?例如,
// This is a useless case only for academic study
var fn = (function outer() {
var localVar1 = 1,
localVar2 = 2;
return function() {};
})();
在这种情况下,fn指的是作为内部函数创建的空函数对象。它没有自由变量。在这种情况下,我们可以说闭合形成了吗?
答案 0 :(得分:9)
Function构造函数创建的函数是否也是闭包?
是的,它关闭了全球范围。这可能是不直观的,因为所有其他JavaScript闭包都关闭了它们的词法范围,但它仍然匹配我们的definition of a closure。在您的示例中,a
是一个自由变量,当在某处调用a
/ inner
函数时,它会解析为另一个范围内的fn
。
如果内部函数没有任何自由变量,我们仍然可以将其称为闭包吗?
取决于你问谁。 Some说是,others打电话给他们"无趣的关闭",我个人说不,因为they don't reference是一个外部范围。
答案 1 :(得分:5)
注意:使用Function构造函数创建的函数不会创建 封闭他们的创作背景;他们总是在 全球范围。运行它们时,它们只能访问 他们自己的局部变量和全局变量,而不是范围内的变量 其中调用了Function构造函数。这不同于 使用eval和函数表达式的代码。