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的引用關系,后期便不可用


.

