module.exports與exports
每一個node.js執(zhí)行文件,都自動創(chuàng)建一個module對象,同時,module對象會創(chuàng)建一個叫exports的屬性有序,初始化的值是 {}
module.exports = {};
Node.js為了方便地導(dǎo)出功能函數(shù)唐含,node.js會自動地實現(xiàn)以下這個語句。
foo.js:
exports.a = function(){
console.log('a')
}
test.js:
var x = require('./foo');
console.log(x.a)
看到這里秕硝,相信大家都看到答案了芥映,exports是引用 module.exports的值。module.exports 被改變的時候远豺,exports不會被改變奈偏,而模塊導(dǎo)出的時候,真正導(dǎo)出的執(zhí)行是module.exports躯护,而不是exports惊来。
Node.js為了方便地導(dǎo)出功能函數(shù),node.js會自動地實現(xiàn)以下這個語句
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不會被改變枉证,而模塊導(dǎo)出的時候矮男,真正導(dǎo)出的執(zhí)行是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)//---> 2
exports在module.exports 被改變后室谚,失效毡鉴。
是不是開始有點廓然開朗,下面將會列出開源模塊中秒赤,經(jīng)持硭玻看到的幾個使用方式。
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里面有一句話倒脓,函數(shù)即對象撑螺,View 是對象,module.export =View, 即相當(dāng)于導(dǎo)出整個view對象崎弃。外面模塊調(diào)用它的時候甘晤,能夠調(diào)用View的所有方法。不過需要注意饲做,只有是View的靜態(tài)方法的時候线婚,才能夠被調(diào)用,prototype創(chuàng)建的方法盆均,則屬于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 = {};
其實,當(dāng)我們了解到原理后泪姨,不難明白這樣的寫法有點冗余游沿,其實是為了保證,模塊的初始化環(huán)境是干凈的肮砾。同時也方便我們诀黍,即使改變了 module.exports 指向的對象后,依然能沿用 exports的特性
exports = module.exports = createApplication;
/**
* Expose mime.
*/
exports.mime = connect.mime;
例子仗处,當(dāng)中module.exports = createApplication
改變了module.exports
了眯勾,讓exports
失效,通過exports = module.exports
的方法婆誓,讓其恢復(fù)原來的特點吃环。
exports.init= function(){}
這種最簡單,直接就是導(dǎo)出模塊 init的方法洋幻。
var mongoose = module.exports = exports = new Mongoose;
集多功能一身郁轻,不過根據(jù)上文所描述的,大家應(yīng)該不能得出答案鞋屈。