export 和 module.export 的區別

本文轉自: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 是 引用的意思,就是兩個變量引用同一個值,是指向同一個內存地址。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章