js 中不同函数的的差异性
2025年7月16日大约 3 分钟
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 = () => {} } | 定义时绑定为实例 | ❌ 否 | ❌ 否 |