应导出构造函数而非其prototype,因实例化后自动继承原型方法;错误导出prototype会导致无法new且this绑定失效;静态方法可挂载在构造函数上统一导出。

在 Node.js 模块中暴露一个构造函数及其原型对象,关键不是“导出 prototype 本身”,而是导出构造函数,让使用者通过 new 实例化后自然继承其原型方法。JavaScript 的原型链机制决定了:只要模块正确导出构造函数,它的 prototype 就天然可被实例访问,无需额外导出 Constructor.prototype。
以下分三部分说明实际做法和常见误区:
构造函数需完整导出,不能只导出实例或方法
Node.js 模块默认导出的是 module.exports 对象。若你想让用户能 new MyService(),就必须把构造函数赋值给 module.exports(或 exports,但推荐前者):
// my-service.js
function MyService(options) {
this.options = options || {};
}
MyService.prototype.init = function() {
console.log('initialized');
};
MyService.prototype.run = function() {
return 'running...';
};
// ✅ 正确:导出构造函数本身
module.exports = MyService;
使用时:
const MyService = require('./my-service');
const instance = new MyService({ debug: true });
instance.init(); // ✅ 可调用原型方法
不要试图单独导出 prototype 对象
MyService.prototype 是一个普通对象,导出它没有意义:
// ❌ 错误示例:导出 prototype 本身 module.exports = MyService.prototype; // 用户拿到的是个对象,无法 new
这样使用者只能:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
const proto = require('./my-service');
proto.init(); // 报错:this 未绑定,且无构造逻辑
原型方法依赖 this 指向实例,脱离构造函数上下文就失去作用。
若需同时导出静态方法和原型方法,统一挂载到构造函数上
常见模式是导出构造函数,并在其上添加静态属性或方法,原型方法则保留在 prototype:
// logger.js
function Logger(name) {
this.name = name;
}
Logger.prototype.log = function(msg) {
console.log(`[${this.name}] ${msg}`);
};
// 静态方法,直接挂在函数上
Logger.createDefault = function() {
return new Logger('default');
};
// ✅ 导出构造函数,静态方法和原型方法都可用
module.exports = Logger;
使用:
const Logger = require('./logger');
const log = new Logger('api');
log.log('started'); // ✅
const def = Logger.createDefault(); // ✅ 静态方法
def.log('using default');
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










