Javascript中的命名函数在声明之前可访问,但函数文字不是

Dav*_*ann 4 javascript function-literal

我试图弄清楚它是如何工作的.当我引用一个尚未声明的命名Javascript函数时,在某些情况下,它可以工作.但是,如果我使用函数文字,它不会,但它也不会失败ReferenceError.

function works() {
    var works_ref = foo;
    function foo() {
        console.log('ok');
    };
    console.log('works ' + works_ref);
}

function fails() {
    var fails_ref = foo;
    var foo = function() {
        console.log('ok');
    };
    console.log('fails ' + fails_ref);
}

works();
fails();
Run Code Online (Sandbox Code Playgroud)

这回来了

"works function foo() {
            console.log('ok');
        }"
"fails undefined"
Run Code Online (Sandbox Code Playgroud)

我想知道第一个例子是如何工作的 - 这是一个解释语言,没有编译,所以我希望任何类型的前向引用都会失败 - 为什么第二个例子不能生成ReferenceError

the*_*eye 5

function foo() {
    console.log('ok');
};
Run Code Online (Sandbox Code Playgroud)

这称为函数声明.这将在编译时处理.所以,JavaScript知道有一个叫做的函数foo.这就是为什么它在这里分配函数对象

var works_ref = foo;
Run Code Online (Sandbox Code Playgroud)

在第二种情况下,

var foo = function() {
    console.log('ok');
};
Run Code Online (Sandbox Code Playgroud)

foo是一个变量,稍后在函数中声明.所以,因为吊装,

var fails_ref = foo;
Run Code Online (Sandbox Code Playgroud)

意识到foo在函数中某处定义的事实,但它不知道它的实际值.因为值赋值var foo = function() {}发生在运行时.这就是为什么默认值undefined用于foo执行实际赋值语句.