我根本不是一个真正的javascript noob,虽然在我的一生中我从未遇到过这个,但我是否正确地假设javascript必须在运行任何东西之前分配函数?
根据我的经验,我希望这会返回'undefined',但很明显它会返回'function'。
function bar() {
return foo;
foo = 10;
function foo() {}
var foo = '11';
}
alert(typeof bar());
有人能为我解释一下吗?
答案 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);
这表明Javascript在执行任何操作之前加载所有函数。因此,定义什么订单功能无关紧要。