前言
在JavaScript学习中,我发现函数声明方式不同会导致行为差异,尤其是const和function声明的函数在提升、作用域等方面表现迥异,这让我产生了深入探究的想法:
JavaScript 中用 const 声明函数和直接用 function 哪个好?
一、两种函数创建方式
在JavaScript中,定义函数主要有两种方式:
1. 函数声明(function declaration)
用 function 的方式叫 函数声明。
函数声明以function关键字开头,接着是必须的函数(变量)名和以逗号分隔的可选的参数列表,再接着就是以大括号封装的函数体。函数声明必须是一个单独的JavaScript语句。必须含有函数名
function f1(arg1,arg2) {
console.log("Hello function 1");
}
核心特性
- 函数提升:函数声明会被提升到当前作用域的顶部,意味着可以在声明前调用函数:
// 可以在声明前调用
f1(); // 输出 "Hello function"
function f1() {
console.log("Hello function");
}
- 允许重复声明:同一作用域内可以重复声明同名函数,后声明的函数会覆盖之前的定义:
function f1() {
console.log("Hello function 1");
}
// 第二个声明覆盖第一个
function f1() {
console.log("Hello function 2");
}
f1(); // 输出 "Hello function 2"
- 动态this绑定:
var name = "Alice"
function f1() {
console.log(this.name);
}
f1(); // 输出"Alice"
函数内部的 this 指向调用时的上下文对象,而非定义时的环境(箭头函数除外)。
2.函数表达式
const 申明函数 叫做 函数表达式
在任何情况下都是其它JavaScript语句的一部分(比如赋值表达式等号的右侧、函数的参数)的函数被称为函数表达式。直接可以运算,函数表达式是直接可以被执行符号执行的。
通过const将匿名函数或箭头函数赋值给变量,语法结构如下:
// 匿名函数表达式
const f2 = function() {
console.log("Hello f2");
};
// 箭头函数表达式(更简洁)
const f3 = () => {
console.log("Hello f3");
};
核心特性
- 块级作用域 通过const声明的函数表达式受块级作用域限制,仅在声明的代码块内有效:
if (true) {
const f2 = () => {
console.log("Hello f2");
};
f2(); // 正常执行
}
// 外部无法访问
// f2(); // 报错:f2 is not defined
- 不可重新赋值 const 声明的变量一旦赋值,无法修改引用(这是 const 的特性,与函数本身无关,let、var 可以重新赋值):
const f2 = () => {
console.log("Hello f2");
};
// 尝试重新赋值会报错
f2 = () => {
console.log("Hello const 2");
};
// TypeError: Assignment to constant variable
- 无函数提升 必须先声明后使用,否则会报错:
// 声明前调用会报错
// f2(); // ReferenceError: Cannot access 'f2' before initialization
const f2 = () => {
console.log("Hello f2");
};
二、关键区别对比
| 特性 | function声明 | const函数表达式 |
|---|---|---|
| 声明方式 | function 函数名() {} | const 函数名 = function/箭头函数 |
| 提升行为 | 函数整体提升(可提前调用) | 仅变量名提升(值为undefined) |
| 作用域 | 函数作用域 | 块级作用域 |
| 重复声明 | 允许(后声明覆盖前声明) | 不允许(Identifier has been declared) |
| 重新赋值 | 允许(通过再次声明或赋值) | 不允许(const特性) |
三、使用场景建议
优先使用function声明的场景
- 需要函数提升特性(如相互递归函数)
- 定义构造函数(需配合 new 关键字使用)
- 全局工具函数或需要跨作用域访问的函数
优先使用const函数表达式的场景
- 模块化开发(限制作用域,避免全局污染)
- 回调函数(如事件处理、数组方法回调)
- 希望确保函数引用不被意外修改的场景
- 使用箭头函数简化代码(如简短的单行逻辑)
如果你不需要函数提升且想要更明确的代码行为,那么使用const声明函数可能是个更好的选择。而如果你需要函数在定义前调用的特性或者是传统习惯,那么function声明也完全没问题。
总结
function声明和const函数表达式各有适用场景,没有绝对的优劣之分。理解它们在提升行为、作用域和可修改性方面的差异,才能在实际开发中做出合适的选择。建议根据项目代码规范和具体业务需求,选择最适合的函数声明方式。