我以为
function foo() { return 42; }
大致相当于
var foo = function() { return 42; }
除了foo.name
在两种情况下都不同。但是关于范围,我认为它会是一样的。
然而,我偶然发现了这段代码:
function demo() {
return foo;
function foo() { return 42; }
}
demo()
实际上会返回foo
函数,即demo()() == 42
。
因此,似乎function
评估可能已经提前完成,可能是在编译阶段。
我的猜测是否正确?那是标准吗? (我正在使用V8。)
(我刚发现this - 它可能是重复的。)
答案 0 :(得分:4)
答案 1 :(得分:1)
使用您的代码示例。
如果你有这个:
alert(foo());
function foo(){ return 42; }
它有效,导致代码解释如下:
function foo(){ return 42; } // declaration is hoisted to the top
alert(foo());
DEMO - 不使用作业
另一方面,如果你有这个:
alert(foo());
var foo = function() { return 42; }
由于undefined is not a function
尚未已定义,结果是alert(foo())
上foo
的运行时例外。
这是因为代码解释如下:
var foo; // foo declaration is hoisted, but not the assignment
alert(foo()); // this will now fail as foo is undefined at this point
foo = function() { return 42; } // the assignment is not hoisted and stays where it is
DEMO - 使用分配(打开控制台查看错误)
其他资源
MDN JavaScript Docs on Var - 请参阅提升部分
答案 2 :(得分:0)
输入execution context时的顺序是在运行任何代码之前处理所有函数和变量声明,因此在使用函数声明时:
function foo(){}
foo 函数将在运行任何代码之前存在。但是,当函数表达式与变量声明(又名initialiser)一起使用时:
var foo = function(){};
虽然 foo 将在任何代码运行之前创建(因为它是使用 var 声明的),但最初会为其分配值 undefined 直到执行分配函数的语句。因此,您可以在声明之前调用声明的函数,但只能在初始化之后调用初始化函数定义的函数。