You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Singleton不是构造函数:两种JS单例实现为何结果不同?

为什么第二个Singleton实现会抛出“Singleton is not a constructor”错误?

这个问题的核心原因非常明确:箭头函数不能被用作构造函数,这是JavaScript箭头函数的核心设计特性决定的。我们来逐一拆解两种实现的差异:

第一种实现(正常工作)

let Singleton = (() => { let instance; function init() { return instance || (instance = this); } return init; })();
let s = new Singleton();
let s2 = new Singleton();
console.log(s == s2); // 输出 true

这里返回的init是一个普通函数,完全符合new操作符对构造函数的要求:

  1. 普通函数拥有自己的prototype属性,new操作符可以基于这个原型创建新对象的原型链。
  2. 当用new调用时,this会被绑定到刚创建的新实例上。
  3. 第一次调用new Singleton()时,instance为undefined,因此instance = this会把新创建的实例存入闭包中的instance变量并返回;后续调用时,直接返回已存在的instance,从而实现单例模式。

第二种实现(报错)

let Singleton2 = (() => { let instance; let init = () => { return instance || (instance = this); } return init; })();
let s1 = new Singleton2(); // 抛出 Uncaught TypeError: Singleton2 is not a constructor

这里返回的init是一个箭头函数,它天生不具备作为构造函数的能力,主要有两个关键原因:

  • 箭头函数没有自己的prototype:new操作符的核心步骤之一是将新对象的__proto__指向构造函数的prototype,但箭头函数根本没有这个属性,引擎直接拒绝用new调用它。
  • 箭头函数没有独立的this绑定:箭头函数的this是继承自定义时的外层作用域(这里是IIFE的全局作用域,this指向window/global),new操作符无法为其绑定新的实例对象作为this。

就算忽略new的限制强行执行,第二个实现里的this也不会是新创建的实例,而是全局对象,最终会把全局对象存入instance,完全达不到单例的预期效果。

内容的提问来源于stack exchange,提问作者Dima Karmazin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:50:25