Node應用由模塊組成,采用CommonJS模塊規范。
根據這個規范,每個文件就是一個模塊,有自己的作用域。在一個文件里面定義的變量、函數、類,都是私有的,對其他文件不可見。
CommonJS規范規定,每個模塊內部,module變量代表當前模塊。這個變量是一個對象,它的exports屬性(即module.exports)是對外的接口。加載某個模塊,其實是加載該模塊的module.exports屬性。
上面代碼通過module.exports輸出變量x和函數addX。
require方法用於加載模塊。
加載:require
語法:
作用:
1、執行被加載模塊中的代碼
2、得到被加載模塊中的exports導出接口對象
導出:exports
Node中是模塊作用域,默認文件中所有的成員只在當前文件模塊有效。
對於希望可以被其它模塊訪問的成員,我們就需要把這些公開的成員都掛載到exports接口對象中就可以了。
1. 導出多個成員(必須在對象中)
2. 導出單個成員
錯誤寫法1
錯誤寫法2
如果一個模塊需要直接導出某個成員,而非掛載的方式,那這個時候必須使用下面這種方式
結果:
只有一個module.exports時,不管是在位置一還是位置二,都為 bar。
當有兩個module.exports 時,比如一個在位置一,另一個在位置三,會導出位置三的對象(module.exports會被后者覆蓋)。
上面的結果出現的原因:exports 和module.exports是有區別的。
在Node中,每個模塊內部都有一個自己的module 對象,該 module 對象中,有一個成員叫exports也是一個對象,類似這樣:
每次導出的對象是module.exports,如果你需要對外導出成員,只需要把導出的成員掛載到module.exports中。
也就是說module.exports才是真正的接口,exports只不過是它的一個輔助工具。最終返回給調用的是module.exports而不是exports。
為了方便,Node為每個模塊提供一個exports變量,指向module.exports。這等同在每個模塊頭部,有一行這樣的命令:
exports相當於是 一個引用,指向module.exports對象,所以有
於是我們可以直接在 exports 對象上添加方法,表示對外輸出的接口,如同在module.exports上添加一樣。注意,不能直接將exports變量指向一個值,因為這樣等於切斷了exports與module.exports的聯系。
同理,給 module.exports 重新賦值也會斷開。
但是這里又重新建立兩者的引用關系:
最后,一定要記得return的是module.exports。
如果給exports賦值,斷開了兩個引用之間的聯系,就不管用了。
exports 和 module.exports 的使用
如果要對外暴露屬性或方法,就用 exports 就行,要暴露對象(類似class,包含了很多屬性和方法),就用 module.exports。