new.target 不能保证绝对安全,但能筑牢第一道防线:确保调度中心基类不被误调、直用或绕过构造逻辑;它通过检查调用方式阻止非 new 调用、禁止基类直用、校验子类契约,并与异步 init 解耦实现稳健启动。
不能靠 new.target 保证“绝对安全”,它只管调用方式,不防数据篡改、竞态、注入或运行时异常。但它能筑牢第一道防线:确保调度中心基类不被误调、不被直用、不被绕过构造逻辑——这是异步流系统稳定启动的前提。
阻止非 new 调用,避免 this 失控
异步流调度中心通常依赖 this 绑定内部队列、事件总线或状态机。若被普通函数调用(如 Scheduler()),严格模式下 this 是 undefined,直接崩溃;非严格模式则指向全局对象,引发隐蔽状态污染。
在基类构造器开头加判断:
-
必须显式使用 new:检查
if (!new.target) throw new TypeError('Scheduler must be instantiated with new') - 该检查应在任何初始化逻辑前执行,包括
super()调用(若继承自其他基类) - 不依赖
arguments.callee或this.constructor,它们在箭头函数、绑定函数或某些压缩场景下不可靠
禁止直接实例化基类,强制派生
调度中心基类本身不实现具体策略(如优先级队列、时间轮、协程挂起),只提供统一生命周期钩子(onStart、onDrain)和资源契约。允许 new Scheduler() 会绕过策略校验,导致流行为不可控。
利用 new.target 精准识别调用源头:
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
- 写
if (new.target === Scheduler) throw new TypeError('Scheduler is abstract: extend and override run()') - 子类如
TimeWheelScheduler继承后调用new TimeWheelScheduler(),此时new.target是子类,条件不触发 - 比
instanceof或this.constructor.name更可靠——后者在动态eval、模块热替换或 Proxy 包裹时可能失真
校验子类是否履行关键契约
仅阻止直用不够。子类可能继承但未实现必需方法(如 run() 执行调度循环,submit(task) 接入任务),导致调度器静默失效。
结合 new.target 和运行时检查:
- 在基类
constructor中,确认new.target.prototype.run是函数:if (typeof new.target.prototype.run !== 'function') throw … - 也可要求子类定义静态属性(如
static requiredStrategy = 'time-wheel'),基类读取new.target.requiredStrategy做预检 - 避免在
this上检查(如!this.run),因为子类构造器尚未执行,方法可能还未绑定
与异步初始化解耦,不干扰 await 流程
调度中心常需异步准备(如连接 Redis 作为任务队列、加载配置)。但 constructor 必须同步返回实例,不能 await。错误做法是把异步逻辑塞进构造器并返回 Promise,这破坏 new 语义。
正确姿势是分两层:
- 构造阶段只做同步校验(
new.target检查 + 契约验证),返回干净实例 - 提供显式异步初始化方法(如
async init()),由使用者主动调用:const s = new TimeWheelScheduler(); await s.init(); -
init()内可检查this._isInitialized标志,防止重复初始化,不依赖new.target,但与其配合形成完整防护链

















