詳解Node.js API系列 Module模組(2) 案例分析
API文件是枯燥的,下面本人收集了一些論壇經常有人疑問和開原始碼中經常遇到的案例供大家研究一下。
module.exports與exports的區別
每一個node.js執行檔案,都自動建立一個module物件,同時,module物件會建立一個叫exports的屬性,初始化的值是 {}
module.exports = {};
Node.js為了方便地匯出功能函式,node.js會自動地實現以下這個語句
foo.js
exports.a = function(){
console.log('a')
}
exports.a = 1
test.js
var x = require('./foo' );
console.log(x.a)
看到這裡,相信大家都看到答案了,exports是引用 module.exports的值。module.exports 被改變的時候,exports不會被改變,而模組匯出的時候,真正匯出的執行是module.exports,而不是exports
再看看下面例子
foo.js
exports.a = function(){
console.log('a')
}
module.exports = {a: 2}
exports.a = 1
test.js
var x = require('./foo');
console.log(x.a)
result:
2
exports在module.exports 被改變後,失效。
是不是開始有點廓然開朗,下面將會列出開源模組中,經常看到的幾個使用方式。
module.exports = View
function View(name, options) {
options = options || {};
this.name = name;
this.root = options.root;
var engines = options.engines;
this.defaultEngine = options.defaultEngine;
var ext = this. ext = extname(name);
if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
this.path = this.lookup(name);
}
module.exports = View;
javascript裡面有一句話,函式即物件,View 是物件,module.export =View, 即相當於匯出整個view物件。外面模組呼叫它的時候,能夠呼叫View的所有方法。不過需要注意,只有是View的靜態方法的時候,才能夠被呼叫,prototype建立的方法,則屬於View的私有方法。
foo.js
function View(){
}
View.prototype.test = function(){
console.log('test')
}
View.test1 = function(){
console.log('test1')
}
module.exports = View
test.js
var x = require('./foo');
console.log(x) //{ [Function: View] test1: [Function] }
console.log(x.test) //undefined
console.log(x.test1) //[Function]
x.test1() //test1
var app = exports = module.exports = {};
其實,當我們瞭解到原理後,不難明白這樣的寫法有點冗餘,其實是為了保證,模組的初始化環境是乾淨的。同時也方便我們,即使改變了 module.exports 指向的物件後,依然能沿用 exports的特性
exports = module.exports = createApplication;
/**
* Expose mime.
*/
exports.mime = connect.mime;
例子,當中module.exports = createApplication
改變了module.exports了,讓exports失效,通過exports
= module.exports的方法,讓其恢復原來的特點。
exports.init= function(){}
這種最簡單,直接就是匯出模組 init的方法。
var mongoose = module.exports = exports = new Mongoose;
集多功能一身,不過根據上文所描述的,大家應該不能得出答案。