是否定义了函数而不管订单?

Sha*_*ins 5 javascript

我根本不是一个javascript noob,虽然在我的一生中我从未遇到过这个,但我是否正确地假设javascript必须在运行任何东西之前分配函数?

根据我的经验,我希望这会返回'undefined',但很明显它会返回'function'.

function bar() {
    return foo;
    foo = 10;
    function foo() {}
    var foo = '11';
}
alert(typeof bar());
Run Code Online (Sandbox Code Playgroud)

有人能为我解释一下吗?

Tom*_*ski 7

JavaScript的这种行为称为提升.MDN有一个很好的解释(https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)

在JavaScript中,函数和变量被提升.提升是JavaScript将声明移动到范围顶部(全局范围或当前函数范围)的行为.

这意味着您可以在声明函数或变量之前使用它,或者换句话说:函数或变量在使用之后可以声明.

基本上,如果你声明一个这样的变量:

console.log(s);             // s === undefined
var s = 'some string';
Run Code Online (Sandbox Code Playgroud)

s声明将被"悬挂"到范围的开头(即没有ReferenceError在线上console.log).该变量的值不会在那一刻,虽然定义.

为变量分配匿名函数也是如此,因此:

console.log(f);             // f === undefined
f();                        // TypeError: f is not a function
var f = function () {};     // assigning an anonymous function as a value
f();                        // ok, now it is a function ;)
Run Code Online (Sandbox Code Playgroud)

变量将被提升并因此在整个范围内可见,但它的值,即使它是一个函数,仍将是未定义的 - 因此如果您尝试执行它则会出错.

另一方面,如果您声明一个命名函数:

console.log(f);             // f === function f()
f();                        // we can already run it
function f() {};            // named function declaration
Run Code Online (Sandbox Code Playgroud)

它的定义也将被提升,因此您甚至可以在您声明它的范围的第一行中运行它.