什么是可见的关闭

What is visible for closure

我正在阅读 "Java Script Ninja" 一书,其中有一章是关于闭包和作用域的。

有代码示例:

var innerHolder;
function outerFunction() {
    console.log("outerFunction: "+x);

    function innerFunction() {
        console.log("innerFunction: "+x);
    }
    innerHolder = innerFunction;
}


console.log("outerScope "+x);
var x = 15
outerFunction();
innerHolder();

结果是:

outerScope undefined

outerFunction: 15

innerFunction: 15

然后书上说:

  1. All variables in an outer scope, even those declared after the function declaration, are included.

  2. Within the same scope, variables not yet defined cannot be forward-referenced.

第二点我理解,但是第一点我不是很清楚。看起来这是真的,但前提是在进行函数调用之前实际声明了变量。在我的逻辑中,因为如果在调用内部函数之后声明变量,则不会提升变量,它当时不在外部范围内,因此不会被闭包选中。对吗?

即如果我修改代码:

console.log("outerScope "+x);
outerFunction();
innerHolder();
var x = 15

结果将是:

outerScope undefined

outerFunction: undefined

innerFunction: undefined

首先所有的函数声明都会被Javascript处理。然后一切都会从左到右处理。

function sayHi(){console.log(x)}; sayHi(); var x = 1; // undefined
function sayHi(){z()}; sayHi(); function z() {console.log(2)}; var x = 1; // 2

所以你是对的。他想向您展示的是 lexical scope 的本质,请参阅随附的 link,您会比从那本书中的示例更好地理解它。

这是您示例中所有内容的执行顺序:

   var innerHolder;// 2 (innerHolder = undefined)
   function outerFunction() { // 1
        console.log("outerFunction: "+x) // 6;

        function innerFunction() { // 7
            console.log("innerFunction: "+x) // 10;
        }
        innerHolder = innerFunction; // 8
    }


    console.log("outerScope "+x); // 3
    var x = 15 // 4
    outerFunction(); //5
    innerHolder(); // 9