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