本文轉自:https://www.jianshu.com/p/e452203d56c4
在瀏覽器端 js 裏面,爲了解決各模塊變量衝突等問題,往往藉助於 js 的閉包把左右模塊相關的代碼都包裝在一個匿名函數裏。而 Nodejs 編寫模塊相當的自由,開發者只需要關注 require,exports,module 等幾個變量就足夠,而爲了保持模塊的可讀性,很推薦把不同功能的代碼塊都寫成獨立模塊,減少各模塊耦合。
在 node 的 js 模塊裏可以直接調用 exports 和 module 兩個“全局”變量,但是 exports 是 module.exports 的一個引用。
//plus.js
function plus(a,b){
return a+b;
}
// 這樣導出的 plus 是作爲 exports 的一個方法被導出的
exports.plus = plus;
// main.js
var Plus = require('plus');
console.log(Plus.plus(1,2)); // 左邊的 Plus 是 require 過來的模塊名,右邊的是它的 plus 方法。
在 node 編譯的過程中,會把 js 模塊封裝成如下形式:
// require 是對 Node.js 實現查找模塊的 Module._load 實例的引用
// __finename 和 __dirname 是 Node.js 在查找該模塊後找到的模塊名稱和模塊絕對路徑
(function(exports,require,module,__filename,__dirname){
function plus(a,b){
return a+b;
}
exports.plus = plus;
})
爲了將函數直接導出成模塊,而不是模塊的一個方法,需要
module.exports = plus;
// plus.js
function plus(a,b){
return a+b ;
}
module.exports = plus;
// main.js
var plus = require('plus');
console.log(plus(1,2));
exports = module.exports = {};
- exports 是 module.exports 的一個引用
- module.exports 初始值爲一個空對象 {},所以 exports 初始值也是 {}
- require 引用模塊後,返回的是 module.exports 而不是 exports!!!
- exports.xxx 相當於在導出對象上掛屬性,該屬性對調用模塊直接可見
- exports = 相當於給 exports 對象重新賦值,調用模塊不能訪問 exports 對象及其屬性
- 如果此模塊是一個類,就應該直接賦值 module.exports,這樣調用者就是一個類構造器,可以直接 new 實例。
例子一:
var name = 'rainbow';
exports.name = name;
exports.sayName = function(){
console.log(name);
}
// 給 exports 賦值相當於給 module.exports 這個空對象添加了兩個屬性,相當於:
var name = 'rainbow';
module.exports.name = name;
module.exports.sayName = function(){
console.log(name);
}
例子二:
exports = module.exports = somethings
// 等價於
module.exports = somethings
exports = module.exports
// module.exports = somethings 是對 mudole.exports 進行了覆蓋,此時 module.exports 和 exports 的關係斷裂,mudole.exports 指向了新的內存塊,而exports 還是指向原來的內存塊,爲了讓 module.exports 和 exports 還是指向同一個內存或者說指向同一個"對象",所以我們就 exports = module.exports.
例子三:
exports = function(){};
// 這樣就是重新給 exports 賦值,它將不再是 module.exports 的引用,二者將無任何聯繫。
例子四:
module.exports.something = function(){};
exports.something = function(){};
// 上面兩個方程是等價的
例子五:
// index.js
var something = require('./requireMe');
something();
// requireMe.js
exports.something = function(){
console.log('am a function');
}
// 以上代碼會報錯,因爲 require 出來的 module.exports 是一個object,不能直接執行
//修改方式一
// requireMe.js
module.exports = function(){
console.log('am a function');
}
// 當把代碼改成上面這樣,就不會報錯,因爲此時的 module.exports 是一個 function,可以直接執行。
// 修改方式二
// index.js
var something = require('./requireMe');
something.something();
// 因爲這時候 require 出來的是一個 object,有一個 something 的屬性,所以可以這樣調用執行。
other:
reference 是 引用的意思,就是兩個變量引用同一個值,是指向同一個內存地址。