對於大多數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