在學習NodeJS的過程中,module是結構化程式基本的組塊。
我們能藉由module將各function block分開來,並且在主程式引用其method或property
然而,要使用module的method或property有許多方式,本文整理常用的幾種並說明特性。
Module基本使用方式
假設我們有二個js程式:app.js和greet.js,想要讓app.js使用greet.js的method,則需要使用module
greet.js1 2 3 4 5
| var greet = function() { console.log('Hello'); }
module.exports = greet;
|
app.js1 2
| var greet = require('./greet'); greet();
|
要在app.js使用greet.js的greet方法,得先require greet.js
require預設是引入javascript檔案,所以副檔名可省略。
而greet.js中,將greet這個函式變數設為module.exports的參考
module.exports其實是個object,供其它js檔案使用其method
上述的寫法可以簡化為:
greet.js1 2 3
| module.exports = function() { console.log('Hello'); }
|
app.js1 2
| var greet = require('./greet'); greet();
|
也是一樣的結果
使用Function Expression
greet2.js1 2 3
| module.exports.greet = function() { console.log('Hello World'); }
|
app.js1 2
| var greet2 = require('./greet2').greet; greet2();
|
利用function expression讓module.exports多一個method
使用Function Constructor
greet3.js1 2 3 4 5 6 7 8
| function Greetr() { this.greeting = 'Hello world!!'; this.greet = function() { console.log(this.greeting); } }
module.exports = new Greetr();
|
app.js1 2
| var greet3 = require('./greet3'); greet3.greet();
|
使用function constructor建立object,並利用this存取function
module.exports則指向新的function constructor
此例有個需要注意的地方,假如我在app.js改變greeting的值,會發生什麼事??
app.js1 2 3 4 5
| var greet3 = require('./greet3'); greet3.greeting = 'Changed';
var greet3b = require('./greet3'); greet3b.greet();
|
改變greeting的值以後,我們再require greet3並且呼叫method,則結果如下:
1 2
| > Hello world!! > Changed
|
這裡帶出一個module重要的特性:NodeJs的核心會cache同一個module的參考,所以當我們宣告greet3b為greet3的object時,其實底層是回傳上一個greet3的參考,而此時greeting己被改變。
所以在不同的js檔案使用同一個module時,需注意其實回傳的都是同一份copy
Function Constructor變形
greet4.js1 2 3 4 5 6 7 8
| function Greetr() { this.greeting = 'Hello world!!!'; this.greet = function() { console.log(this.greeting); } }
module.exports = Greetr;
|
app.js1 2 3
| var greet4 = require('./greet4'); var greetr = new greet4(); greetr.greet();
|
這種方式把建構子放在app.js,所以不會有二個require指向同一份copy
Revealing Module Pattern
greet5.js1 2 3 4 5 6 7 8 9
| var greeting = 'Hello JS!'; function greet() { console.log(greeting); }
module.exports = { greet: greet }
|
app.js1 2
| var greet5 = require('./greet5').greet; greet5();
|
這裡我們使用object並把greet指向greet methond,所以module.exports只能存取greet而不會改到其它值
這種方式也稱為Revealing Module Pattern,在javascript中是常用的包裝方式。
以上為NodeJS使用module.exports的幾種方式。