一、內部原理
exports = module.exports = {}
exports 是 module.exports 的引用,怎么理解這句話呢?大概就是 var a = {}; var b = a; a 和 b 之間的關系吧。
1、require:在文件中 require 實際引入的是 module.exports 里面返回的東西
2、module:module 實際上是一個對象,里面有很多屬性,包括 exports 等。
為什么可以直接打印 module,而不會報錯呢?—— 因為當每個文件被執行的時候,內部都會執行 var module = new Module() 實例被創建。
3、module.exports:給module實例中的exports對象添加的屬性或者方法;
4、exports:直接打印 exports 是個空對象,且不會報錯。因為內部執行了 var module = new Module(); var exports = module.exports
5、示例分析:
(1)正確示例:可以看到實例對象module中的exports對象中新增了add 方法和name屬性
console.log(module); module.exports.add = function (x, y) { return x + y }; exports.name = name; console.log(module);
(2)錯誤示例1:重新改變module.exports的指向之后,exports.xxx 添加屬性無效
因為exports指向的還是之前的舊對象,exports.xxx 是往之前指向的對象中添加屬性,但是module.exports所指向的是一個新的對象,所以實例對象中的exports對象只有add方法,name屬性沒有添加進去;
console.log(module); module.exports = { add: function(x,y) { return x + y } } exports.name = 'tom'; console.log(module);
(3)錯誤示例2:重新改變exports的指向之后,exports.xxx添加屬性無效
因為require的原理就是引入module.exports里返回的內容,可以用exports添加屬性和方法,是由於內部添加了一條exports = module.exports的引用,讓exports指向了module.exports,所以更改exports的指向之后,就不會對module.exports中的內容有任何的影響了。
console.log(module); module.exports.add = function (x, y) { return x + y }; exports = { name: 'tom'}; console.log(module);
二、exports 與 module.exports 使用
1、將函數直接導出成模塊
// 模塊文件:./my_modules/m.js
function fn1(){ console.log('我是fn1') } module.exports=fn1; // index.js
var foo=require('./my_modules/m') foo(); // 我是fn1
2、如果模塊文件中有兩個函數,第二個會覆蓋第一個
function fn1(){ console.log('我是fn1') } function fn2(){ console.log('我是fn2') } module.exports=fn1; module.exports=fn2; // index.js
var foo=require('./my_modules/m') foo();//我是fn2
3、如何導出模塊中的所有函數
...... module.exports.fn1=fn1; module.exports.fn2=fn2; var foo=require('./my_modules/m') foo.fn1();//我是fn1
foo.fn2();//我是fn2
4、exports 是 module.exports 的一個引用,exports = module.exports = {}
exports.xxx 相當於在導出對象上掛屬性,該屬性對調用模塊直接可見
// 模塊文件:./my_modules/m.js
exports.fn1=function(){ console.log('我是fn1') } exports.fn2=function(){ console.log('我是fn2') } // index.js
var foo=require('./my_modules/m') foo.fn1();//我是fn1
foo.fn2();//我是fn2
5、小結區別:
(1)module.exports=xxx,相當於導出某個函數或對象等內容,在另一個文件中引用后可直接使用
(2)exports.xxx 和 module.exports.xxx 相當於把函數或變量掛載在對象上,在另一個文件中應用后,通過調用對象屬性和方法進行使用。
(3)exports 是 module.exports 的一個引用,exports = module.exports = {}
