简而言之 exports是 module.exports本地文件中的快捷方式(相当于引用),它不能实很好的实现导出功能。
a.js
exports.f = 123123
b.js
const a = require('./a');
console.log(a.f);
这样可以正常从a导出,在b.js中引用
a.js中改为exports = {f: 123}
无法导出
a.js中改为module.exports = {f: 123}
正常导出
以下为官方文档翻译:
module.exports#
Added in: v0.1.16
-
<Object>
module.exports
对象是由Module系统创建的,有时这是不能被接受的;很多人希望他们的module是一些class的实例。为此,将期望导出的对象赋值到module.exports。需要注意的是赋值期望的对象到exports
会简单的将本地exports
变量重新绑定,这很可能并不是所期望的结果。
The
module.exports
object is created by the Module system. Sometimes this is not acceptable; many want their module to be an instance of some class. To do this, assign the desired export object tomodule.exports
. Note that assigning the desired object toexports
will simply rebind the localexports
variable, which is probably not what is desired.
举个例子,假设我们建了一个叫a.js
的模块
For example suppose we were making a module called a.js
const EventEmitter = require('events');
module.exports = new EventEmitter();
// Do some work, and after some time emit
// the 'ready' event from the module itself.
// 搞点事情,过一秒之后将'ready'事件从模块自身提交出去
setTimeout(() => {
module.exports.emit('ready');
}, 1000);
在另一个文件中我们可以这么做
Then in another file we could do
const a = require('./a');
a.on('ready', () => {
console.log('module a is ready');
});
要注意给module.exports
赋值必须立即执行,而不能在回调中进行,以下为错误示例:
Note that assignment to module.exports must be done immediately. It cannot be done in any callbacks. This does not work:
x.js:
setTimeout(() => {
module.exports = { a: 'hello' };
}, 0);
y.js:
const x = require('./x');
console.log(x.a);
exports shortcut#
Added in: v0.1.16
exports
变量在模块的文件级范围内是有效的,并且会在模块评估之前被赋值为module.exports
的值
它允许有一个快捷键,所以module.exports.f = ...
可以更简洁的写为exports.f = ...
然而,要意识到,和其他变量一样,假如有一个新的值被赋到exports
上,那么它将不再绑定到module.exports
:
The
exports
variable is available within a module's file-level scope, and is assigned the value ofmodule.exports
before the module is evaluated.It allows a shortcut, so that
module.exports.f = ...
can be written more succinctly asexports.f = ....
However, be aware that like any variable, if a new value is assigned toexports
, it is no longer bound tomodule.exports
:
module.exports.hello = true; // Exported from require of module 从需求模块中导出
exports = { hello: false }; // Not exported, only available in the module 没有导出,仅在模块中有效
当module.exports
属性被完全替换为一个新的对象时,通常也会重新赋值exports
,例如:
When the module.exports
property is being completely replaced by a new object, it is common to also reassign exports
, for example:
module.exports = exports = function Constructor() {
// ... etc.
};
为了阐明这个行为,猜想一下require()
的假想实现(比实际简单很多):
To illustrate the behavior, imagine this hypothetical implementation of require()
, which is quite similar to what is actually done by require()
:
function require(/* ... */) {
const module = { exports: {} };
((module, exports) => {
// Module code here. In this example, define a function.
function someFunc() {}
exports = someFunc;
// At this point, exports is no longer a shortcut to module.exports, and
// this module will still export an empty default object.
module.exports = someFunc;
// At this point, the module will now export someFunc, instead of the
// default object.
})(module, module.exports);
return module.exports;
}
网友评论