詳解nodejs中exports和module.exports的區(qū)別
require 用來加載代碼,而 exports 和 module.exports 則用來導(dǎo)出代碼。但很多新手可能會迷惑于 exports 和 module.exports 的區(qū)別,為了更好的理解 exports 和 module.exports 的關(guān)系,我們先來鞏固下 js 的基礎(chǔ)。示例:
app.js
var a = {name: 'nswbmw 1'}; var b = a; console.log(a); console.log(b); b.name = 'nswbmw 2'; console.log(a); console.log(b); var b = {name: 'nswbmw 3'}; console.log(a); console.log(b);
運(yùn)行 app.js 結(jié)果為:
{ name: 'nswbmw 1' } { name: 'nswbmw 1' } { name: 'nswbmw 2' } { name: 'nswbmw 2' } { name: 'nswbmw 2' } { name: 'nswbmw 3' }
解釋一下:a 是一個(gè)對象,b 是對 a 的引用,即 a 和 b 指向同一個(gè)對象,即 a 和 b 指向同一塊內(nèi)存地址,所以前兩個(gè)輸出一樣。當(dāng)對 b 作修改時(shí),即 a 和 b 指向同一塊內(nèi)存地址的內(nèi)容發(fā)生了改變,所以 a 也會體現(xiàn)出來,所以第三、四個(gè)輸出一樣。當(dāng)對 b 完全覆蓋時(shí),b 就指向了一塊新的內(nèi)存地址(并沒有對原先的內(nèi)存塊作修改),a 還是指向原來的內(nèi)存塊,即 a 和 b 不再指向同一塊內(nèi)存,也就是說此時(shí) a 和 b 已毫無關(guān)系,所以最后兩個(gè)輸出不一樣。
明白了上述例子后,我們進(jìn)入正題。
我們只需知道三點(diǎn)即可知道 exports 和 module.exports 的區(qū)別了:
- exports 是指向的 module.exports 的引用
- module.exports 初始值為一個(gè)空對象 {},所以 exports 初始值也是 {}
- require() 返回的是 module.exports 而不是 exports
所以:我們通過
var name = 'nswbmw'; exports.name = name; exports.sayName = function() { console.log(name); }
給 exports 賦值其實(shí)是給 module.exports 這個(gè)空對象添加了兩個(gè)屬性而已,上面的代碼相當(dāng)于:
var name = 'nswbmw'; module.exports.name = name; module.exports.sayName = function() { console.log(name); }
我們通常這樣使用 exports 和 module.exports
一個(gè)簡單的例子,計(jì)算圓的面積:
使用 exports
app.js
var circle = require('./circle'); console.log(circle.area(4));
circle.js
exports.area = function(r) { return r * r * Math.PI; }
使用 module.exports
app.js
var area = require('./area'); console.log(area(4));
area.js
module.exports = function(r) { return r * r * Math.PI; }
上面兩個(gè)例子輸出是一樣的。你也許會問,為什么不這樣寫呢?
app.js
var area = require('./area'); console.log(area(4));
area.js
exports = function(r) { return r * r * Math.PI; }
運(yùn)行上面的例子會報(bào)錯。這是因?yàn)?,前面的例子中通過給 exports 添加屬性,只是對 exports 指向的內(nèi)存做了修改,而
exports = function(r) { return r * r * Math.PI; }
其實(shí)是對 exports 進(jìn)行了覆蓋,也就是說 exports 指向了一塊新的內(nèi)存(內(nèi)容為一個(gè)計(jì)算圓面積的函數(shù)),也就是說 exports 和 module.exports 不再指向同一塊內(nèi)存,也就是說此時(shí) exports 和 module.exports 毫無聯(lián)系,也就是說 module.exports 指向的那塊內(nèi)存并沒有做任何改變,仍然為一個(gè)空對象 {} ,也就是說 area.js 導(dǎo)出了一個(gè)空對象,所以我們在 app.js 中調(diào)用 area(4) 會報(bào) TypeError: object is not a function 的錯誤。
所以,一句話做個(gè)總結(jié):當(dāng)我們想讓模塊導(dǎo)出的是一個(gè)對象時(shí),exports 和 module.exports 均可使用(但 exports也不能重新覆蓋為一個(gè)新的對象),而當(dāng)我們想導(dǎo)出非對象接口時(shí),就必須也只能覆蓋 module.exports。
我們經(jīng)??吹竭@樣的用寫法:
exports = module.exports = somethings;
上面的代碼等價(jià)于
module.exports = somethings; exports = module.exports;
原因也很簡單,module.exports = somethings 是對 module.exports 進(jìn)行了覆蓋,此時(shí) module.exports 和 exports 的關(guān)系斷裂,module.exports 指向了新的內(nèi)存塊,而 exports 還是指向原來的內(nèi)存塊,為了讓 module.exports 和 exports 還是指向同一塊內(nèi)存或者說指向同一個(gè) “對象”,所以我們就 exports = module.exports。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
Node.js?內(nèi)置模塊fs文件系統(tǒng)操作示例詳解
這篇文章主要為大家介紹了Node.js?內(nèi)置模塊fs文件系統(tǒng)操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02關(guān)于node.js版本npm -v報(bào)錯問題的解決方法
最近工作中遇到了些問題,這里總結(jié)下,下面這篇文章主要給大家介紹了關(guān)于node.js版本npm -v報(bào)錯問題的解決方法,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04Highcharts+NodeJS搭建數(shù)據(jù)可視化平臺示例
本篇文章主要介紹了Highcharts+NodeJS搭建數(shù)據(jù)可視化平臺,詳細(xì)的介紹了使用Highcharts框架的經(jīng)驗(yàn),有興趣的可以了解一下。2017-01-01使用nodejs、Python寫的一個(gè)簡易HTTP靜態(tài)文件服務(wù)器
這篇文章主要介紹了使用nodejs、Python寫的一個(gè)簡易HTTP靜態(tài)文件服務(wù)器,分為nodejs和Python兩個(gè)版本,用類似淘寶的CSS、JS文件加載方式處理靜態(tài)文件加載,需要的朋友可以參考下2014-07-07Node.js利用Express實(shí)現(xiàn)用戶注冊登陸功能(推薦)
這篇文章主要介紹了Node.js利用Express實(shí)現(xiàn)用戶注冊登陸功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10