面试官:函数声明和函数表达式有什么区别

开发 前端
函数声明会被提升,可以在定义前调用,而函数表达式不会提升,必须先赋值再调用。函数表达式适用于回调、IIFE,而函数声明适用于普通函数.

在 JavaScript 中,我们可以通过 函数声明(Function Declaration) 和 函数表达式(Function Expression) 来定义函数。它们在提升(Hoisting)、可读性、作用域等方面有所不同。

1. 语法区别

函数声明(Function Declaration)

function sayHello() {
  console.log("Hello, world!");
}

特点

  • 使用 function 关键字直接定义函数。
  • 必须有函数名(sayHello)。
  • 可被提升(Hoisting),可以在声明前调用。

函数表达式(Function Expression)

const sayHello = function() {
  console.log("Hello, world!");
};

特点

  • 将函数赋值给变量(const sayHello = ...)。
  • 匿名函数(Anonymous Function)或具名函数(Named Function Expression):

a.匿名函数:function() {}(大多数情况下使用)

b.具名函数:function myFunc() {}(仅在调试时有用)

  • 不会被提升(Hoisting),只能在定义后调用。

2. 提升(Hoisting)

函数声明会被提升

函数声明在 JavaScript 解析阶段 就会被提升,因此可以在声明前调用

sayHello(); // ✅ 可以调用
function sayHello() {
  console.log("Hello, world!");
}

解析阶段

// 解析时,相当于:
function sayHello() { 
  console.log("Hello, world!"); 
}
sayHello(); // 正常执行

函数表达式不会被提升

数表达式不会被提升,只有在执行到赋值代码后才可以调用:

sayHello(); // ❌ 报错:Cannot access 'sayHello' before initialization
const sayHello = function() {
  console.log("Hello, world!");
};

解析阶段

const sayHello; // 变量存在,但未赋值
sayHello(); // ❌ 报错
sayHello = function() { console.log("Hello, world!"); };

结论:

  • 函数声明:可在定义前调用
  • 函数表达式:必须先定义再调用

3. 作用域 & 调试

具名函数表达式的优势

如果使用 具名函数表达式(Named Function Expression, NFE):

const sayHello = function greet() {
  console.log("Hello, world!");
};
sayHello(); // ✅ 正常调用
greet(); // ❌ 报错:greet is not defined
  • sayHello() 可用
  • greet() 仅在函数内部可用(局部作用域),但在外部不可访问。
  • 好处:

a.提升调试能力:错误栈中会显示 greet,而不是 anonymous function。

4. 是否可用作 IIFE(立即执行函数表达式)

函数表达式支持 IIFE

(function() {
  console.log("立即执行!");
})(); // ✅ 立即执行
  • IIFE(Immediately Invoked Function Expression,立即执行函数) 需要函数表达式。
  • 函数声明无法用于 IIFE,否则会报错:
function() {
  console.log("错误示例");
}(); // ❌ 语法错误

结论:

  • IIFE 只能用函数表达式,不支持函数声明.

5. 面试高频问题

 面试官:函数声明和函数表达式的本质区别?
回答

  • 函数声明会被提升,可以在定义前调用;函数表达式不会被提升,只能在赋值后调用。
  • 函数声明更适合普通函数,函数表达式更适合动态函数、回调和 IIFE。

面试官:函数表达式能被提升吗?回答:

  • 变量名会被提升,但不会赋值。所以不能在定义前调用:
console.log(myFunc); // ❌ undefined
const myFunc = function() {}; // 这里才赋值

面试官:什么时候用函数表达式?回答:

  • 当函数是回调时(如 setTimeout、事件监听器)。
  • 当函数需要立即执行(IIFE)。
  • 当需要匿名或具名函数表达式(例如递归或调试)。

总结

对比项

函数声明

函数表达式

定义方式

function funcName() {}

const func = function() {}

提升(Hoisting)

✅ 提升,可在声明前调用

❌ 不提升,必须先定义再调用

是否必须命名

✅ 必须有函数名

✅ 匿名或具名

适合场景

适用于普通函数

适用于回调、IIFE

是否支持 IIFE

❌ 不支持

✅ 支持

面试高分回答:

“函数声明会被提升,可以在定义前调用,而函数表达式不会提升,必须先赋值再调用。函数表达式适用于回调、IIFE,而函数声明适用于普通函数。” 

责任编辑:姜华 来源: 大迁世界
相关推荐

2017-08-01 00:19:15

Javascript函数函数声明

2011-05-30 16:11:46

Javascript

2021-06-28 08:01:57

JS 函数表达式函数声明

2023-02-17 08:10:24

2024-09-19 08:42:43

2024-04-03 15:33:04

JWTSession传输信息

2021-11-30 07:44:50

FinalFinallyFinalize

2021-12-10 12:01:37

finalfinallyfinalize

2021-12-13 06:56:45

Comparable元素排序

2024-03-20 15:12:59

KafkaES中间件

2021-12-23 07:11:31

开发

2023-02-09 07:01:35

转发重定向Java

2023-07-11 08:40:02

IO模型后台

2025-01-20 09:02:00

列表推导生成器表达式Python

2021-07-08 06:51:29

React函数组件

2024-09-04 17:35:09

2023-12-13 13:31:00

useEffect对象浏览器

2023-02-20 07:19:14

2022-05-16 11:04:43

RocketMQPUSH 模式PULL 模式

2024-03-26 16:24:46

分布式事务2PC3PC
点赞
收藏

51CTO技术栈公众号