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