[ Node ] module.exports 和 exports

module 对象

在每个模块中, module 的自由变量是对表示当前模块的对象的引用。 为方便起见,还可以通过全局模块的 exports 访问 module.exports。 module 实际上不是全局的,而是每个模块本地的。

 

module.exports

module.exports 对象由 Module 系统创建。 有时这是不可接受的;许多人希望他们的模块成为某个类的实例。 为此,需要将期望导出的对象赋值给 module.exports。 将期望的对象赋值给 exports 会简单地重新绑定本地的 exports 变量,这可能不是所期望的。

例如,假设正在创建一个名为 a.js 的模块:

const EventEmitter = require('events');

module.exports = new EventEmitter();

// 处理一些工作,并在一段时间后从模块自身触发 'ready' 事件。
setTimeout(() => {
  module.exports.emit('ready');
}, 1000);

然后,在另一个文件中可以这么做:

const a = require('./a');
a.on('ready', () => {
  console.log('模块 a 已准备好');
});

对 module.exports 的赋值必须立即完成。 不能在任何回调中完成。 以下是不起作用的:

x.js:

setTimeout(() => {
  module.exports = { a: 'hello' };
}, 0);

y.js:

const x = require('./x');
console.log(x.a);

exports 快捷方式

exports 变量是在模块的文件级作用域内可用的,且在模块执行之前赋值给 module.exports

它允许使用快捷方式,因此 module.exports.f = ... 可以更简洁地写成 exports.f = ...。 但是,就像任何变量一样,如果为 exports 赋予了新值,则它将不再绑定到 module.exports

module.exports.hello = true; // 从模块的引用中导出。
exports = { hello: false };  // 不导出,仅在模块中可用。

当 module.exports 属性被新对象完全替换时,通常也会重新赋值 exports

module.exports = exports = function Constructor() {
  // ... 
};

为了说明这种行为,想象对 require() 的假设实现,它与 require() 的实际实现非常类似:

function require(/* ... */) {
  const module = { exports: {} };
  ((module, exports) => {
    // 模块代码在这。在这个例子中,定义了一个函数。
    function someFunc() {}
    exports = someFunc;
    // 此时,exports 不再是一个 module.exports 的快捷方式,
    // 且这个模块依然导出一个空的默认对象。
    module.exports = someFunc;
    // 此时,该模块导出 someFunc,而不是默认对象。
  })(module, module.exports);
  return module.exports;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值