require 用來加載代碼,而 exports 和 module.exports 則用來導出代碼。但很多新手可能會迷惑于 exports 和 module.exports 的區別,為了更好的理解 exports 和 module.exports 的關系,我們先來鞏固下 js 的基礎。示例:
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);運行 app.js 結果為:
{ name: 'nswbmw 1' }{ name: 'nswbmw 1' }{ name: 'nswbmw 2' }{ name: 'nswbmw 2' }{ name: 'nswbmw 2' }{ name: 'nswbmw 3' }解釋一下:a 是一個對象,b 是對 a 的引用,即 a 和 b 指向同一個對象,即 a 和 b 指向同一塊內存地址,所以前兩個輸出一樣。當對 b 作修改時,即 a 和 b 指向同一塊內存地址的內容發生了改變,所以 a 也會體現出來,所以第三、四個輸出一樣。當對 b 完全覆蓋時,b 就指向了一塊新的內存地址(并沒有對原先的內存塊作修改),a 還是指向原來的內存塊,即 a 和 b 不再指向同一塊內存,也就是說此時 a 和 b 已毫無關系,所以最后兩個輸出不一樣。
明白了上述例子后,我們進入正題。
我們只需知道三點即可知道 exports 和 module.exports 的區別了:
所以:我們通過
var name = 'nswbmw';exports.name = name;exports.sayName = function() { console.log(name);}給 exports 賦值其實是給 module.exports 這個空對象添加了兩個屬性而已,上面的代碼相當于:
var name = 'nswbmw';module.exports.name = name;module.exports.sayName = function() { console.log(name);}我們通常這樣使用 exports 和 module.exports
一個簡單的例子,計算圓的面積:
使用 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;}上面兩個例子輸出是一樣的。你也許會問,為什么不這樣寫呢?
app.js
var area = require('./area');console.log(area(4));area.js
exports = function(r) { return r * r * Math.PI;}運行上面的例子會報錯。這是因為,前面的例子中通過給 exports 添加屬性,只是對 exports 指向的內存做了修改,而
exports = function(r) { return r * r * Math.PI;}其實是對 exports 進行了覆蓋,也就是說 exports 指向了一塊新的內存(內容為一個計算圓面積的函數),也就是說 exports 和 module.exports 不再指向同一塊內存,也就是說此時 exports 和 module.exports 毫無聯系,也就是說 module.exports 指向的那塊內存并沒有做任何改變,仍然為一個空對象 {} ,也就是說 area.js 導出了一個空對象,所以我們在 app.js 中調用 area(4) 會報 TypeError: object is not a function 的錯誤。
所以,一句話做個總結:當我們想讓模塊導出的是一個對象時,exports 和 module.exports 均可使用(但 exports也不能重新覆蓋為一個新的對象),而當我們想導出非對象接口時,就必須也只能覆蓋 module.exports。
我們經常看到這樣的用寫法:
exports = module.exports = somethings;
上面的代碼等價于
module.exports = somethings;exports = module.exports;
原因也很簡單,module.exports = somethings 是對 module.exports 進行了覆蓋,此時 module.exports 和 exports 的關系斷裂,module.exports 指向了新的內存塊,而 exports 還是指向原來的內存塊,為了讓 module.exports 和 exports 還是指向同一塊內存或者說指向同一個 “對象”,所以我們就 exports = module.exports。
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持武林網!
新聞熱點
疑難解答