JavaScript三种函数声明格式的差异、适用场景及选用时机
三种JavaScript函数写法的差异与适用场景
嘿,太懂这种困惑了!刚入门JS的时候,看着这几种写法功能好像差不多,真的会越看越懵。咱们就从好理解的表层角度,把这三种写法掰扯明白~
1. 函数表达式(const counter1 = function(num) { ... })
- 写法本质:这是把一个匿名函数(也可以写具名的,但外部用不了那个内部名字)赋值给了一个变量,相当于“用变量存了个函数”
- 核心区别:
- 遵循变量提升规则:只有变量声明会被提前,赋值不会。也就是说,你不能在
const counter1这行代码之前调用counter1(),会直接报错 - 函数本身默认是匿名的(除非特意加内部名字,比如
function myCounter(num) { ... },但外部只能用counter1调用)
- 遵循变量提升规则:只有变量声明会被提前,赋值不会。也就是说,你不能在
- 适合用的场景:
- 需要把函数当“值”传递的时候,比如给
setTimeout、数组map/filter当回调函数 - 只想在某个局部作用域里用这个函数,避免污染全局命名空间
- 需要根据条件动态切换函数逻辑的情况(比如
const func = isAdmin ? adminFunc : userFunc)
- 需要把函数当“值”传递的时候,比如给
2. 函数声明(function counter2(num) { ... })
- 写法本质:直接用
function关键字声明一个带名字的函数,属于JS里的“常规函数声明” - 核心区别:
- 有函数提升:不管你把这个函数写在代码的哪个位置,JS引擎都会提前把它“拎”到当前作用域的最顶部。所以你甚至可以在函数声明的代码之前就调用
counter2(),完全没问题 - 自带的函数名在整个作用域都能访问,写递归的时候直接用这个名字就行,不用额外处理
- 有函数提升:不管你把这个函数写在代码的哪个位置,JS引擎都会提前把它“拎”到当前作用域的最顶部。所以你甚至可以在函数声明的代码之前就调用
- 适合用的场景:
- 作为通用工具函数,比如那些会在代码多个地方调用的求和、格式化日期的函数
- 需要递归调用的函数(不用纠结递归的命名问题)
- 希望函数在整个作用域内都能被提前调用的场景
3. 箭头函数(const counter3 = (num) => { ... })
(你没写完的第三种应该是箭头函数,这是现在非常常用的简化写法)
- 写法本质:用
=>替代function的精简写法,语法更紧凑 - 核心区别:
- 没有自己的
this:它的this直接继承外层作用域的this,不会像普通函数那样在调用时乱变(这对新手来说简直是福音,再也不用头疼this的各种坑了) - 不能当构造函数用(不能用
new关键字调用它) - 没有
arguments对象,如果要获取所有参数,用剩余参数...args就行 - 语法可以更精简:只有一个参数时能省略括号,函数体只有一行返回语句时能省略大括号和
return,比如const double = num => num * 2
- 没有自己的
- 适合用的场景:
- 当回调函数用,尤其是需要固定
this指向的场景(比如对象方法里的回调、React组件的事件处理) - 写逻辑简单的短函数,比如数组
map/filter里的回调,代码会清爽很多 - 不需要自己的
this、也不需要构造函数的场景
- 当回调函数用,尤其是需要固定
简单总结下:表层看功能确实差不多,但它们在提升规则、this指向、使用限制上有实打实的区别。选哪种主要看你是否需要函数提前调用、是否要处理this、以及是否要把函数当作值传递~
内容的提问来源于stack exchange,提问作者maze
相关产品推荐
相关产品推荐

