exports和module.exports區別
1、分析
我們可以從底層實現去理解:在node里每個模塊內部都有一個自己的對象module,而該module對象里,有一個子對象exports
在node里,誰require該文件,誰就得到module.exports接口對象
我們發現,每次導出接口成員時通過module.exports.xxx = xxx的方式很麻煩,都得通過點.方式 因此node為了簡化操作,專門提供了一個變量:exports = module.exports
也就是說在模塊底層實現里,還有這么一句代碼
var exports = module.exports
測試如下
2、原理解析
exports是module.exports的一個引用
3、導出單個模塊
當導出單個模塊時,需要module.exports即可
4、思考進階(面向對象--引用類型)
為什么導出單個對象不可以使用exports = xxx;直接賦值定義導出???
原理圖:引用數據類型
接下來再看個思考題
結果為hello,為什么呢?
當給obj1重新賦值后,它便指向了新對象,開辟了新的內存空間,如下所示,此時兩者已經沒有關系
綜上分析不能使用exports = xxx來直接導出單個成員
var exports = module.exports
類似於
var obj1 = obj
這里exports只是module.exports的一個引用,所以這里直接給exports直接賦值,並不會影響module.exports,只是指向了新對象而已。
始終要記住:底層實現里最后返回的是module.exports對象
5、重新賦值,解除引用
此外,這里要注意:一旦給exports重新賦值,便會失去和module.exports的關聯,指向新對象,且后期無法使用。
如下所示
6、思考2
對上述代碼再次修改如下
結果如下
7、思考3
再使用module.exports添加如下
8、思考4
接下來再做下調整
原理如下:
換為exports與module.exports
重定義
這里注意:此時兩者已經沒有引用關系,最終return的是module.exports所以只需要看module.exports即可
9、思考5
接着修改代碼
10、思考6
11、小結
1、exports為modules.exports的一個引用 2、最后node底層模塊導出的是module.exports 3、底層代碼 var module = { exports:{...} } 4、exports.name等價於module.exports.name,但node為了方便書寫,使用module.exports導出單個成員,本質為將該子對象重新賦值
5、所以只要給exports賦值,便丟失了module.exports的引用關系,后期便不可用
.