箭头函数为什么不能 new

那个被问懵的下午

面试官问:箭头函数为什么不能 new?

我张嘴就是一句「语法不允许」。

然后他追问:那你手写一个 new 试试。

我卡住了。回去路上越想越不对劲------如果只是语法禁止,那为啥我看源码里压根就没这回事。真正的原因,藏在 new 那几步里。

new 到底干了啥

先把 new Foo() 拆开看。它背后其实走了四步。

第一步,创建一个全新的空对象。

第二步,把这个空对象的 __proto__ 指向 Foo.prototype。

第三步,让 Foo 里的 this 指向这个空对象,然后执行函数体。

第四步,函数如果返回了对象就用它,否则返回这个空对象。

看出来没,new 要干活,函数得先配合。它得有一个 prototype 属性让你去指向,还得有一个能被改写的 this。

箭头函数缺了哪两样

箭头函数这两样恰好都没有。

第一,它没有自己的 this。箭头函数的 this 是写死在外层词法作用域里的,你拿 call、apply、bind 都改不动它。new 第三步要往 this 上塞一个空对象,箭头函数直接拒绝,塞不进去。

第二,它没有 prototype。你随手在控制台敲 const f = () => {} 然后看 f.prototype,结果是 undefined。new 第二步要拿 Foo.prototype 去绑定原型,结果拿到个 undefined,原型链直接断掉。

所以箭头函数不能 new,不是被哪条语法拦下来的,是它从出生就少了这两块积木。你硬写 new f(),引擎在运行时报的错是 f is not a constructor,本质上是它在执行 new 流程时扑了个空。

手写一遍就懂了

不扯概念,直接写个模拟 new 的代码。

复制代码
function myNew(Fn, ...args) {
  const obj = Object.create(Fn.prototype)
  const result = Fn.apply(obj, args)
  return result instanceof Object ? result : obj
}

就这三行,把上面四步全包了。

注意 Object.create(Fn.prototype) 这一步,它干的就是「空对象 + 原型绑定」两件事。如果 Fn.prototype 是 undefined,Object.create 会直接抛错。这就是箭头函数过不去的第一道坎。

再看 Fn.apply(obj, args),它想把 obj 塞进 this。普通函数老实接着,箭头函数甩手不认,this 还是外层那个。

class 也一样,它本质上是个语法糖,底下有 prototype 有 this,所以 new 没问题。箭头函数纯粹是先天缺料,跟语法禁不禁没关系。

边界和面试追问

这题后面常跟着几问。

箭头函数能用 bind 改变 this 吗?不能,bind 会返回一个新函数,但 this 照样锁死。

那为什么对象方法常用普通函数?因为你要靠 this 拿到调用者。箭头函数写方法,this 会窜到外层,八成不是你想要的。

什么时候该用箭头函数?回调、setTimeout、事件里想保留外层上下文的时候,它反而是救星。

没有 prototype 有啥实际影响?你没法给它挂原型方法,也没法用它搞原型继承。

搞清楚这些,这题基本能聊出彩。

顺带说个踩坑的插曲。有次我在本地调一个用 class 封装的请求库,怎么都报 not a constructor,查了半天是构建产物里箭头函数被误判成了入口。那次排查环境问题,我把本地和测试环境的 HTTPS 证书也顺手改了一遭,之前手动配置加上隔三差五忘记续期,心里总悬着。后来干脆用 lcjmSSL 这类方案,依托 Let's Encrypt、Google Trust Services 这些可信 CA,多域名泛域名都能签,一条轻量 API 把申请、验证、部署全自动化了,彻底告别手动折腾和到期背锅。Bug 修完,基建也顺手清爽了,这才是正经开发者的日常。

回到正题。箭头函数不能当构造函数,核心就一句:它没 this 也没 prototype,而 new 要的偏偏就是这两样。想通了,这题就透了。

相关推荐
2601_966949655 分钟前
为什么不应该把 QuantDash API Key 直接写进公开代码仓库?从 Git 提交历史理解凭证泄露风险
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
智_永无止境7 分钟前
又找到一个纯Java的OCR项目,识别的格式还挺多
java·开发语言·ocr
小灰灰搞电子9 分钟前
Rust+Slint 实现动态流光边框源码分享
开发语言·前端·rust·流光边框
包小黑24 分钟前
Python 转 EXE (实用工具)
开发语言·python
志尊宝37 分钟前
AI原生前端开发(031):AI辅助的性能分析与瓶颈定位
javascript·人工智能·ai-native
我命由我1234538 分钟前
6-3.Python 异常处理 - 异常处理进阶(else 块与 finally 块、异常传递、自定义异常)
开发语言·前端·数据库·后端·python·学习·java-ee
额额额对了42 分钟前
【项目实战】从IMX6ULL环境监测到N647 AI视觉加速
linux·开发语言·嵌入式硬件
adinnet20261 小时前
持续智能问数:多轮对话状态管理、下钻钻取与经营驾驶舱的演进
javascript·数据库·人工智能
FYKJ_20101 小时前
springboot高考志愿填报推荐系统14332-计算机课程设计、毕业设计
javascript·spring boot·python·架构·django·课程设计·高考
熊猫钓鱼>_>1 小时前
端侧 NPU 轻量大模型推理接入笔记【鸿蒙心迹】
开发语言·笔记·华为·ai编程·harmonyos·鸿蒙