箭头函数不能用 new 是因缺乏 [[Construct]] 内部方法,运行时直接抛错;但“不可被 new”不等于“纯函数”,纯度取决于无副作用和确定性输出,需靠工具链、约定和代码设计保障。

箭头函数确实不支持 new.target,但这本身不是“特性”而是设计限制——它根本不能被 new 调用,尝试会直接抛出 TypeError: Arrow functions are not constructors。所以,**你不需要、也无法“利用”这个限制去“强行约束”箭头函数作为纯函数执行**,因为它天然就不具备构造函数行为。
为什么箭头函数不能用 new?
这是语言规范层面的硬性限制:
- 箭头函数没有
[[Construct]]内部方法,而new操作符必须调用该方法; - 它没有自己的
this、arguments、super或new.target; - 试图
new (() => {})会在运行时立即报错,不会进入函数体。
纯函数 ≠ 不能 new 的函数
“纯函数”指:相同输入始终返回相同输出,且无副作用(不修改外部状态、不依赖可变外部变量、不执行 I/O 等)。而“不可被 new”只是调用方式限制,二者无逻辑关联:
- 普通函数可以是纯的,也可以是不纯的,还能被
new(比如new Date()); - 箭头函数虽不可
new,但仍可能不纯(例如捕获并修改外部变量、调用Math.random()、发起fetch); - 真正保障纯度,靠的是代码逻辑和开发约定,不是语法糖的限制。
如果你真想约束函数只作纯函数使用
可以结合以下实践,而非依赖箭头函数的 new.target 缺失:
-
静态检查:用 TypeScript + ESLint 插件(如
eslint-plugin-functional)标记副作用、禁止非纯操作; -
运行时防御:在函数开头检查
this是否为undefined(箭头函数中this是词法绑定,但普通函数若被new调用,this是新对象),不过这不适用于箭头函数本身; -
命名与文档:用
const add = (a, b) => a + b;这类声明,并在注释中标明// @pure,配合工具链识别; -
避免闭包污染:不捕获可变外部变量,或显式冻结依赖(如
const config = Object.freeze({...}))。
小结
箭头函数不能 new 是事实,但它不是纯度的保证,也不需要你“利用”这个限制去“强行约束”。纯函数的关键在于行为可控、无隐式依赖与副作用。把注意力放在函数内部逻辑、依赖管理与工具链支持上,比纠结语法能否被 new 更有效。


















