JavaScript函数声明与函数表达式的区别及作用域分析

作者:拾光

时间:2026-10-28

浏览:459

本文深入解析JavaScript中函数声明与函数表达式的核心区别。重点探讨函数提升(Hoisting)机制对两者执行顺序的影响,区分匿名与命名函数表达式的语法特征,并详细分析变量赋值时机与内部作用域可见性规则,帮助开发者避免ReferenceError等常见错误。

文章目录

函数声明与提升机制

函数声明


function foo() {}

函数 foo 会在程序正式执行前被提升(hoist),这意味着它在定义所在的作用域内始终可用。即便在函数定义代码之前尝试调用它,也不会报错。


foo(); // Works because foo was created before this code runs
function foo() {}

关于作用域的详细内容将在后续专门文章中介绍,此处暂不展开。

函数表达式的分类与判断

函数表达式

与函数声明不同,函数表达式中的函数名并非必需。因此,根据是否包含名称,函数表达式可分为匿名函数表达式和命名函数表达式两类。具体示例如下:

函数声明的标准格式为 function functionName() {}。而函数表达式允许省略名称,写作 function functionName[可选]() {}。判断关键在于:若整个函数体作为表达式的一部分出现,则属于函数表达式;否则即为函数声明。以下是合法的表达式写法:


var fuc = foo(){}

再列举几个极端的表达式构造示例:


!function foo(){}
true && function foo(){}

上述写法仅用于区分函数表达式的概念,实际开发中极少这样编写。通过对比示例可以更直观地观察其执行效果:


foo1();//foo1 is not defined 
foo2();//works because foo2 was created before this code runs
!function foo1() {
  alert('foo1 works');
};
function foo2() {
  alert('foo2 works');
};

匿名函数表达式

匿名函数表达式


var foo = function() {};

上述示例将一个匿名函数赋值给了变量 foo。


foo; // 'undefined'
foo(); // this raises a TypeError
var foo = function() {};

由于 var 关键字会触发变量提升(hoist),使得变量 foo 在程序执行阶段已存在且可被引用。然而,赋值操作仅在运行时执行,因此此时变量 foo 的值仍为 undefined。

命名函数表达式

命名函数表达式

接下来讨论将命名函数赋值给变量的情况。


var foo = function bar() {
  bar(); // Works
};
bar(); // ReferenceError

在此场景中,命名函数 bar 被赋值给了变量 foo。因此,在函数定义外部无法访问该函数,但在 bar 函数内部依然可以正常调用。这是由 JavaScript 处理命名函数的机制决定的:函数名仅在函数内部的作用域中有效。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章