new.target用于控制插件基类的实例化入口:强制new调用防this错误、禁止直接实例化抽象基类、动态适配子类行为、支持双模式调用,实现安全复用与上下文感知。

用 new.target 编写通用插件基类,核心不是“加功能”,而是“控入口”——它帮你天然区分谁在实例化、谁在继承、谁在误调用。这种控制力让基类既能防滥用,又能灵活适配不同子类行为,真正实现“一处定义、多处安全复用”。
强制插件必须通过 new 实例化
避免用户漏写 new 导致 this 指向错误或污染全局,是插件健壮的第一道防线。
- 在构造函数开头检查
!new.target,直接抛错 - 不依赖
this instanceof PluginBase等运行时判断,更可靠(ES5 兼容写法易出错) - 错误信息明确指向调用方式问题,利于调试
class PluginBase {
constructor(options = {}) {
if (!new.target) {
throw new TypeError('PluginBase 必须使用 new 调用');
}
this.options = { ...this.defaultOptions, ...options };
}
get defaultOptions() { return {}; }
}
设计仅可继承、不可直接实例化的抽象基类
有些插件逻辑只提供能力骨架(如事件总线、配置校验、生命周期钩子),本身无意义。用 new.target 锁定其“被继承”定位。
- 判断
new.target === PluginBase,为真则禁止实例化 - 子类调用
super()时,父类中new.target自动指向子类,无需额外传参 - 比手动检查
constructor.name更安全(防重命名、防压缩混淆)
class PluginBase {
constructor() {
if (new.target === PluginBase) {
throw new TypeError('PluginBase 是抽象基类,不可直接实例化');
}
this.id = Symbol('plugin-instance');
}
}
class ModalPlugin extends PluginBase {
constructor(config) {
super(); // 此时 new.target 在父类中为 ModalPlugin
this.config = config;
}
}
在继承链中动态响应实际构造类
子类可能需要差异化初始化(比如不同插件对同一套基类逻辑启用不同默认行为),new.target 提供了无需参数传递的上下文感知能力。
- 基类中根据
new.target.name或new.target本身做分支处理 - 支持基于类名的策略映射(如
new.target.name === 'ChartPlugin' ? enableCanvas : enableSVG) - 配合静态属性(如
supportedFeatures)可构建声明式扩展机制
class PluginBase {
constructor() {
const ctor = new.target;
this.features = ctor.supportedFeatures || [];
this.logger = ctor.createLogger?.() || console;
}
}
class ChartPlugin extends PluginBase {
static supportedFeatures = ['export', 'theme'];
static createLogger() {
return new CustomLogger('chart');
}
}
兼容普通函数调用的“双模式”插件封装
部分场景需兼顾传统函数调用习惯(如 modal({title: 'x'}))与面向对象实例(如 new Modal({title: 'x'}))。new.target 是唯一能干净分离两种路径的原生方案。
- 检测
new.target存在与否,自动返回实例或执行快捷流程 - 普通调用时可内部创建并返回新实例,避免暴露构造细节
- 保持 API 表面简洁,底层仍享有类封装带来的可维护性
function PluginFactory(options) {
if (!new.target) {
return new PluginFactory(options); // 普通调用 → 自动补 new
}
this.options = options;
this.init();
}
PluginFactory.prototype.init = function() {
// 初始化逻辑
};

















