對於大多數node初學者而言, module.exports應該都是理解的, 但多出來一個exports獲取就有些疑問了
疑問一: 既然有module.exports了為什么還要有exports?
疑問二: 兩者有什么區別?
首先, 官網是這么回答的
The exports variable is available within a module's file-level scope, and is assigned the value of module.exports before the module is evaluated.
It allows a shortcut, so that module.exports.f = ... can be written more succinctly as exports.f = ....
也就是說, exports相當於一個快捷方式,exports.f = .... 肯定是比 module.exports.f = ... 寫起來方便一些。下面附上一段express源碼中的使用你就明白了。
exports = module.exports = createApplication;
exports.mime = connect.mime;
exports.application = proto;
exports.request = req;
exports.response = res;
function createApplication() {
var app = connect();
merge(app, proto);
app.request = { __proto__: req, app: app };
app.response = { __proto__: res, app: app };
app.init();
return app;
}
其實exports是將指針執行module.exports對象, 如果你像exports = function(){}這樣相當於改變了exports原來的指向, 也就無法被導出, 為什么?先看官網給的類似實現:
function require(/* ... */) {
const module = { exports: {} };
((module, exports) => {
// 你的模塊代碼在這。在這個例子中,定義了一個函數。
function someFunc() {}
exports = someFunc;
// 此時,exports 不再是一個 module.exports 的快捷方式,
// 且這個模塊依然導出一個空的默認對象。
module.exports = someFunc;
// 此時,該模塊導出 someFunc,而不是默認對象。
})(module, module.exports);
return module.exports;
}
根據上面的代碼可以看出exports是模塊內部一個形參對象, 如果給exports對象添加屬性是可以導出的, 因為指針並未改變, 但如果賦值一個對象就不行了, 因為指針已經改變了,最后導出的是module.exports
