函数作用域中的JavaScript函数变量

函数作用域中的JavaScript函数变量,javascript,Javascript,我以为 function foo() { return 42; } 基本相当于 var foo = function() { return 42; } 除了foo.name在这两种情况下有所不同。但是关于范围,我认为应该是一样的 然而,后来我偶然发现了以下代码: function demo() { return foo; function foo() { return 42; } } 而demo()实际上返回foo函数,即demo()()==42 所以,函数的求值可能已经

我以为

function foo() { return 42; }
基本相当于

var foo = function() { return 42; }
除了
foo.name
在这两种情况下有所不同。但是关于范围,我认为应该是一样的

然而,后来我偶然发现了以下代码:

function demo() {
    return foo;

    function foo() { return 42; }
}
demo()
实际上返回
foo
函数,即
demo()()==42

所以,
函数
的求值可能已经在更早的时候完成了,可能是在编译阶段

我的猜测正确吗?这是标准吗?(我使用的是V8。)


(我刚刚发现-可能是重复的。)

函数定义如下:

function foo() { return 42; }
提升至其容纳功能的顶部


解释作用域和提升。

输入函数时的顺序是在运行任何代码之前处理所有函数和变量声明,因此使用函数声明时:

function foo(){}
foo函数将在运行任何代码之前存在。但是,当函数表达式与变量声明(又名an)一起使用时:


虽然foo将在运行任何代码之前创建(因为它是用var声明的),但在执行分配函数的语句之前,它最初将被分配未定义的值。因此,您可以在声明之前调用声明的函数,但只能在初始化后调用初始化器定义的函数。

使用您的代码示例

如果您有:

alert(foo());
function foo(){ return 42; }
它可以工作,因为代码的解释如下:

function foo(){ return 42; } // declaration is hoisted to the top
alert(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

-不使用赋值


另一方面,如果您有:

alert(foo());
var foo = function() { return 42; }
由于
foo
尚未定义,因此导致运行时异常
undefined不是在线
alert(foo())
上的函数

这是因为代码的解释如下:

function foo(){ return 42; } // declaration is hoisted to the top
alert(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

-使用分配(打开控制台查看错误)


其他资源



-参见提升章节

功能提升。
“功能评估似乎已经在前面完成了”
-这不是所谓的功能评估,但本质上是肯定的。定义为
function foo()
的任何内容本质上都会被移动(提升)到作用域的顶部。下面是另一篇简洁友好的文章:在没有var的情况下声明foo的唯一方法是使用函数声明,在这种情况下,它仍然被声明。忘记“吊装”,这是一个不应该使用的行话,它不在语言规范中。通过赋值隐式创建全局变量与所谓的“提升”无关(看看术语未定义时会发生什么?)。对未声明变量的赋值将创建具有该名称的全局对象的属性,与已声明的属性类似,只是在执行赋值代码并删除它们之前不会创建此类属性。没有提升,没有移动,没有处理无序。所有代码首先从上到下进行解析。正是在这个阶段处理声明。然后是代码执行。如果解释器在最底层发现不可解析的代码,它将根本不执行任何代码。错误也没有被“提升”。