JavaScript 中的每个函数都是闭包是真的吗?

Is it true that every function in JavaScript is a closure?

我知道 JavaScript 中的每个函数都是第一个 class 对象,并且它有一个内部 属性 [[scope]] 用于托管函数的绑定记录变量。但是,有两种特殊情况。

  1. Function构造函数创建的函数也是闭包吗? Function constructor 创建的函数对象比较特殊,因为它的 [[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.
    

    这是不直观的。这也叫闭包吗?

  2. 如果一个内部函数没有任何自由变量,我们是否可以说在创建内部函数时就形成了一个闭包?例如,

    // This is a useless case only for academic study
    var fn = (function outer() {
        var localVar1 = 1,
            localVar2 = 2;
        return function() {};
    })();
    

    在这种情况下,fn 指的是作为内部函数创建的空函数对象。它没有自由变量。在这种情况下我们可以说形成了闭包吗?

Is the function created by Function constructor also a closure?

是的,它在全球范围内关闭。这可能不直观,因为所有其他 JavaScript 闭包都关闭了它们的词法范围,但它仍然匹配我们的 definition of a closure。在您的示例中,a 是一个自由变量,并在某处调用 inner/fn 函数时解析为其他范围内的 a

If an inner function doesn't have any free variables, can we still call it a closure?

取决于你问的是谁。 say Yes, others call them "uninteresting closures", personally I say No because they don't reference 一个外部作用域。

Note: Functions created with the Function constructor do not create closures to their creation contexts; they always are created in the global scope. When running them, they will only be able to access their own local variables and global ones, not the ones from the scope in which the Function constructor was called. This is different from using eval with code for a function expression.

来自 https://developer.mozilla.org