寫在前面:本文轉自博友:wbxjiayou的文章:node.js中module.export與export的區別。javascript
多是有史以來最簡單通俗易懂的有關Module.exports和exports區別的文章了。html
exports = module.exports = {};java
因此module.exports
和exports
的區別就是var a={}; var b=a;
,a和b的區別node
看起來木有什麼太大區別,但實際用起來的時候卻又有區別,這是爲啥呢,請聽我細細道來api
關於Module.exports和exports有什麼區別,網上一搜一大把,可是說的都太複雜了…
據說exports是Module.exports對象的一個引用(reference)^1,什麼是引用?!…_(:з」∠)_函數
固然啦,若是要完全理解這兩個導出的區別,最好確定是去看源碼,看看都是怎麼封裝的,功力深厚的童鞋應該一看就懂了。不過,源碼我也是看不懂的…(ಥ_ಥ)post
可是最近感受雜七雜八看了好多文章作了好多實驗以後,像是打開了任督二脈,機智的我好像有點上道了…ui
首先要明確的一點,module是一個對象 {Object}
。
當你新建一個文件,好比mo.js,文件內容以下:url
1 |
console.log(module); |
而後在CMD裏執行這個文件node mo.js
,就能看到module實際上是一個Module實例,你能夠這麼理解,NodeJS中定義了一個Module類,這個類中有不少屬性和方法,exports是其中的一個屬性:spa
1 |
function Module { |
當每一個js文件在執行或被require的時候,NodeJS其實建立了一個新的實例var module = new Module()
,這個實例名叫module
。
這也就是爲何你並無定義module
這個變量,卻能console.log出來而不會報錯的緣由。
假設我有一個JS文件內容以下:
console.log(module); //你會看到Module中的exports爲空對象{} module.exports = { print : function(){console.log(12345)} } console.log(module); //你會看到Module中的exports對象已經有了print()方法
有了上面的基礎,很容易理解module.export
實際上是給Module實例中的exports對象中添加方法/屬性。
一般使用exports的時候,是這麼用的:
exports.print = function(){console.log(12345)}
假設我有一個JS文件內容以下:
console.log(module); //你會看到Module中的exports爲空對象{} console.log(exports); //你會看到Module中的exports爲空對象{} module.exports = { print : function(){console.log(12345)} } console.log(module); //你會看到Module中的exports對象有了print()方法 exports.name = '小白妹妹'; console.log(module); //你會看到Module中的exports對象不只有了print()方法,還有了name屬性
由此也能看出,傳說中的exports
實際上是module.exports
的引用,你能夠這麼理解,NodeJS在你的代碼以前悄悄的加了如下代碼:
var module = new Module(); var exports = module.exports;
這也就是爲何你並無定義exports
這個變量,卻能console.log出來而不會報錯的緣由。
當你從外部調用某個模塊,require實際上是在require什麼?^2
require的時候NodeJS會處處去找有沒有這個模塊,若是有,return的就是module.exports裏的東東。
module.exports.name = '小白妹妹'; exports.age = 10; module.exports.print = function(){console.log(12345)};若是隻是使用
.
來添加屬性和方法,module.exports
和exports
混用是徹底能夠的,這種狀況下,感受exports
就是給懶人用的…畢竟能少寫幾個7個字符呢!module.exports = { name = '小白妹妹'; }; exports.age = 10; module.exports.print = function(){console.log(12345)};
module.exports = { name = '小白妹妹'; }; exports = {age:10}; // exports如今是{age:10}這個對象的引用,再也不是module.exports的引用了 console.log(module); //你會看到Module的exports中只有name屬性!!!
exports.age = 10; console.log(module); //你會看到Module的exports中多了age屬性 module.exports = { name = '小白妹妹'; }; console.log(module); //你會看到Module的exports中仍是隻有name屬性!!!
module.exports
和exports
的區別就是var a={}; var b=a;
,a和b的區別
- 改變
exports
的指向後所添加的exports.xxx
都是無效的。由於require返回的只會是module.exports
exports.xxx
以後,改變module.exports
的指向。由於exports.xxx
添加的屬性和方法並不存在於module.exports
所指向的新對象中。exports
對象上module.exports
對象上,不要和導出屬性值混在一塊兒