JavaScript函数声明与函数表达式的区别及作用域分析
本文深入解析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 处理命名函数的机制决定的:函数名仅在函数内部的作用域中有效。
JS处理含Emoji或中文的字符串转数组乱码问题
2026-11-05 16:12:28
JS怎么使用展开运算符合并对象
2026-11-05 14:42:18
ES6+环境下判断JS对象为空的简洁写法
2026-11-05 12:12:23
怎么通过replacer函数自定义JS中JSON的格式化输出
2026-11-05 11:19:44
JS正则表达式基础:字面量与RegExp构造函数的区别及常用元字符
2026-11-05 11:16:58
