nodejs里的module.exports和exports
引
在node.js中我們可以使用module.exports和exports導(dǎo)出模塊,設(shè)置導(dǎo)出函數(shù)、數(shù)組、變量等等
為什么可以用這兩個模塊?
或者直接問,node.js的模塊功能是怎么實現(xiàn)的。
這樣得益于javascript是函數(shù)性的語言,并支持閉包。
js的閉包
直接看w3cschool吧,感覺講的挺好的:js閉包
node.js的模塊實現(xiàn),大致代碼
首先準備一個nodejs規(guī)范的代碼:
hello.js
Node.js加載了hello.js后,它把這段代碼包裝一下,大概變成這樣:
var module = {id: 'hello',exports: {} }; var load = function () {// 實際我們自己編寫的hello.js代碼:function greet(name) {console.log('Hello, ' + name + '!');}module.exports = greet;// hello.js代碼結(jié)束return module.exports; }; var exports = load(); // 保存module: save(module, exports);module是nodejs自動加的一個對象,可見,初始化的時候會先對module.exports賦值一個空的對象{}。
save(module, exports);這個函數(shù)是個真·全局函數(shù),作用是把exports這個變量存到某個全局變量中。其它模塊通過require()函數(shù)實際上就是去這個全局變量里把對應(yīng)的值拿出來。
這樣,看js代碼大概就明白了,為什么在nodejs里可以直接用module.exports和exports這兩個語法。
module.exports和exports
module.exports和exports實際上都是對一個對象的引用,這個對象初始化就是一個空對象{}。所以直接就可以使用類似
示例一: module.exports.foo = function () { return 'foo'; }; module.exports.bar = function () { return 'bar'; }; 或者示例二: exports.foo = function () { return 'foo'; }; exports.bar = function () { return 'bar'; };這兩個示例作用是一樣的,其本質(zhì)都是往最開始初始化的空數(shù)組里添加成員。
示例三 module.exports = {hello: hello,greet: greet };示例三就不一樣了,實際上module.exports重新引用到了一個新的對象里。如果示例三前面有示例一或者二的代碼,那么會最終導(dǎo)致示例一或者二導(dǎo)出的模塊丟掉。
示例四 exports = {hello: hello,greet: greet };示例四看上去雖然和示例三差不多,但是這種寫法實際上并沒有輸出任何變量!注意看nodejs的實現(xiàn)代碼,load()函數(shù)里最后return的是module.exports,也就是說最后save的是module.exports的引用對象,而示例四中exports被賦值了一個新的對象,此時module.exports和exports引用的已經(jīng)不是同一個對象了!
那么提問:示例三雖然對module.exports重新引用到了一個新的對象,最終結(jié)果也能實現(xiàn)模塊的正常導(dǎo)出,那么示例三里的exports此時引用的是什么對象呢?
最后,如果你打算導(dǎo)出一個數(shù)組或者變量,或者函數(shù),都會涉及到module.exports原引用對象的丟棄,要額外注意,此時要小心不要丟掉前面已經(jīng)導(dǎo)出的模塊。
結(jié)論
如果要輸出一個鍵值對象{},可以利用exports這個已存在的空對象{},并繼續(xù)在上面添加新的鍵值;
如果要輸出一個函數(shù)或數(shù)組,必須直接對module.exports對象賦值。
所以我們可以得出結(jié)論:直接對module.exports賦值,可以應(yīng)對任何情況:
module.exports = {foo: function () { return 'foo'; } }; 或者: module.exports = function () { return 'foo'; };最終,我們強烈建議使用module.exports = xxx的方式來輸出模塊變量,這樣,你只需要記憶一種方法。
或者使用我喜歡的方法,對空對象直接添加值:
var foo = function () { return 'foo'; };...module.exports.foo = foo;// module.exports.bar = function () { return 'bar'; };參考
liaoxuefeng
exports 和 module.exports 的區(qū)別
w3cschool
JS是按值傳遞還是按引用傳遞?,但是我不是很同意文中所說的按共享傳遞這名字的叫法。實際上無論傳遞普通變量還是傳遞函數(shù),都是按值拷貝傳遞,只不過傳遞對象的時候,拷貝過去的是個引用變量罷了,即引用副本。
這里就是c語言指針的思想。
如果你對我上面所講的還不明白,建議去把c語言里的指針好好的重學一遍。真正理解透徹了c里面的指針,學起來其它所有語言都不怕。
轉(zhuǎn)載于:https://www.cnblogs.com/acbingo/p/7709363.html
總結(jié)
以上是生活随笔為你收集整理的nodejs里的module.exports和exports的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab中数组创建方法
- 下一篇: Jenkins的maven工程打包的时候