详解JavaScript中的函数声明和函数表达式

作者:纸飞机时间:2026-10-29 13:00:17浏览:271

本文深入解析JavaScript中创建函数的两种主要方式:函数声明与函数表达式,并介绍自执行函数表达式。重点阐述JavaScript引擎的变量提升(hoisting)机制,通过代码示例对比分析两者在提升行为上的差异,揭示变量被提升为undefined与函数体被完整提升的区别,并简要提及函数构造法及其局限性。

JavaScript函数创建的基本方法

在JavaScript中,创建函数主要有两种途径:函数声明和函数表达式,它们的具体语法形式分别如下所示:

函数声明与函数表达式的区别


// 方法一:函数声明

function foo() {}


// 方法二:函数表达式
var foo = function () {};

此外,还存在一种自执行函数表达式(IIFE),其核心目的是构建独立的作用域,确保内部声明的变量不会与外部作用域发生命名冲突或混淆。这类函数通常以匿名形式存在,并在定义后立即自动执行:


(function () {
  // var x = ...
})();

这种自执行函数表达式本质上属于上述第二种方法,即归类为函数表达式的一种特殊应用。

虽然方法一和方法二都创建了一个名为foo的函数,但两者在执行机制上存在显著差异。JavaScript解释器具备一种名为变量声明提升(hoisting)的机制,这意味着变量(包括函数声明)的声明部分会被自动移动到其所在作用域的顶部。即便代码书写顺序位于底部,声明仍会被提升至作用域的最前端。

参考以下代码片段:

变量提升机制详解


alert(foo); // function foo() {}
alert(bar); // undefined
function foo() {}
var bar = function bar_fn() {};
alert(foo); // function foo() {}
alert(bar); // function bar_fn() {}

上述代码的输出结果依次为:function foo() {}、undefined、function foo() {}以及function bar_fn() {}。

观察可知,尽管foo的声明语句位于alert调用之后,它依然能被正确调用。这是因为JavaScript解释器会将函数声明提升至alert之前。相比之下,通过函数表达式创建的函数bar则不具备这种提升特性。

那么,bar是否真的没有被提升呢?实际上,使用var声明的变量确实会被提升,只是其初始值被赋为undefined。因此,第二个alert弹出的结果是undefined。

基于此,JavaScript引擎执行上述代码的实际顺序可能如下所示:

  • 首先创建变量foo和bar,并将它们都初始化为undefined。
  • 接着处理函数foo的函数体,并将其赋值给变量foo。
  • 然后执行前两个alert语句。
  • 随后创建函数bar_fn,并将其赋值给变量bar。
  • 最后执行后两个alert语句。

注意:

严格来说,在JavaScript中创建函数还有一种方法,被称为“函数构造法”:

函数构造法及其局限性


var foo = Function('alert("hi!");');
var foo = new Function('alert("hi!");'); // 等同于上面一行

该方法接收一个字符串作为参数来构建函数体。然而,这种方式在执行效率上会有所降低,且似乎无法直接传递参数,因此在实际开发中建议谨慎使用。

作者最新文章