js 中不同函数的的差异性
2025年8月12日大约 4 分钟
js 中不同函数的的差异性
js 中的函数编写的六种方式
- 函数声明(Function Declaration)
/**
* 使用function声明一个函数
* 这种方式声明的函数会发生变量提升,即 先调用再定义,这样并不会抛出异常
*/
function fn() {}
- 函数表达式(Function Expression)
/**
* 使用这种方式声明的函数,不会发生变量提升,
* 即 在声明前调用,会抛出异常
*/
const fn = function () {}
- 箭头函数(Arrow Function)(ES6+)
/**
* 箭头函数不会发生变量提升
* 没有this,arguments、super、new.target这些属性
*/
const fn = () => {}关于 arguments,浏览器环境和 node 环境会得到不同的结果
在浏览器中,

但是在 node 环境中
)
但是这里实际输出的并不是函数的 arguments,
这个主要是 node 的模块包装机制的意外注入
node.js 在每个模块文件(比如 .js 文件)运行前,会自动用一个函数包裹你的代码:
;(function (exports, require, module, __filename, __dirname) {
// 你写的所有代码都在这里面
})箭头函数就从外层“词法作用域”继承到了 arguments。
箭头函数的没有自己的 this 指向,它的 this 继承自他的外部作用域,不受调用方式的影响。不能被 bind,call,apply 修改,也就是说箭头函数的指向是在定义是就指定的无法再被修改。
- 匿名函数(Anonymous Function)
/**
* 匿名函数就是函数表达式的一种,不命名
*/
setTimeout(function () {
console.log('延迟执行')
}, 1000)- 命名函数表达式(Named Function Expression)
/**
* 内部可以通过greet调用,外部只能通过func调用
*/
const func = function fn() {}- 构造函数方式(Function 构造器)
/**
* 使用较少
*/
const sayHello = new Function('name', 'return "Hello, " + name;')- 立即执行函数
/**
* 常用于模块隔离,变量私有化
*/
;(function () {
console.log('立即执行')
})()this 指向问题
| 函数类型 | 定义方式示例 | this 绑定方式 | this 是否随调用方式变化 | 是否可被 bind 改变 |
|---|---|---|---|---|
| 普通函数(声明式) | function fn() {} | 动态绑定 | ✅ 是 | ✅ 是 |
| 普通函数(表达式) | const fn = function() {} | 动态绑定 | ✅ 是 | ✅ 是 |
| 对象方法 | const obj = { fn() {} } | 动态绑定 | ✅ 是 | ✅ 是 |
| 构造函数 | function Person() {} → new Person() | 新对象绑定 | ❌ 否 | ❌ 无效 |
| 箭头函数(Arrow) | const fn = () => {} | 定义时词法绑定 | ❌ 否 | ❌ 否 |
| Class 方法 | class A { method() {} } | 动态绑定 | ✅ 是 | ✅ 是 |
| Class 中箭头函数属性 | class A { method = () => {} } | 定义时绑定为实例 | ❌ 否 | ❌ 否 |
背景
「js 中不同函数的的差异性」属于语言语义边界主题。该类问题在重构阶段最容易引发“代码没报错但行为变了”的隐性风险。
核心原理
需要同时理解语法定义与运行时行为:作用域、提升规则、this 绑定、短路语义、类型判定边界。
实现方式 / 示例
建议每个结论都配“正例 + 反例 + 适用边界”,并明确推荐写法与禁用写法。
常见问题
- 只背结论,不验证边界。
- 在不同场景复用同一写法,忽略语义差异。
- this 绑定策略不统一时,回调上下文错误会在重构后集中暴露。
最佳实践
将知识点同步到 ESLint 规则、代码评审清单与模板代码,形成自动化约束。
总结
围绕「js 中不同函数的的差异性」的关键不是记忆语法,而是把语义边界沉淀为可执行规范。
