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

时间:2015-07-10 07:55:57

标签: javascript

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

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

function bar() {
    return foo;
    foo = 10;
    function foo() {}
    var foo = '11';
}
alert(typeof bar());

有人能为我解释一下吗?

3 个答案:

答案 0 :(得分:7)

JavaScript的这种行为称为提升。 MDN(https://developer.mozilla.org/en-US/docs/Glossary/Hoisting

有一个很好的解释
  

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

     

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

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

console.log(s);             // s === undefined
var s = 'some string';

s声明将被提升为#34;到范围的开头(即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 ;)

变量将被提升并因此在整个范围内可见,但它的值,即使它的功能仍然未定义 - 因此如果你错误尝试执行它。

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

console.log(f);             // f === function f()
f();                        // we can already run it
function f() {};            // named function declaration

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

答案 1 :(得分:0)

在JavaScript函数中,只有Object。

当您说 typeof bar()时,在 bar函数中,您将返回 foo 这是另一个函数。您只需返回名称函数,那么,它返回 foo 函数的构造函数。所以,你的 typeof 获取 foo构造函数的值,这是函数的类型。那么,它提醒功能。由于 closure

,它仍然会引用 foo

再次在 bar 定义中,你返回 foo ,但仍然没有遇到它的定义。在JavaScript中,当解析指令时,声明变量和函数在当前功能范围的顶部。

所以, 你的陈述

function bar() {
    return foo;
    foo = 10;
    function foo() {}
    var foo = '11';
}

相当于

function bar() {
    function foo() {}
    return foo;
    foo = 10;

    var foo = '11';

这称为JavaScript top hoist

}

答案 2 :(得分:0)

这很容易测试;

foo(1);

function foo(i) {
    if (bar()) {
        alert("foo called, bar true, i = " + i);
    };
}

foo(2);

function bar() {
    return true;
}

foo(3);

DEMO

这表明Javascript在执行任何操作之前加载所有函数。因此,定义什么订单功能无关紧要。