node.js 模块加载原理

 来自BYVoid的《Node.js+开发指南》

2015-9-14 11:23:30

有时候我们只是想把一个对象封装到模块中,例如:

//singleobject.js
function Hello() {
    var name;
    this.setName = function (thyName) {
    name = thyName;
};
this.sayHello = function () {
    console.log('Hello ' + name);
};
};
exports.Hello = Hello;

此时我们在其他文件中需要通过 require('./singleobject').Hello 来获取
Hello 对象,这略显冗余,可以用下面方法稍微简化:

//hello.js
function Hello() {
    var name;
    this.setName = function(thyName) {
    name = thyName;
};
this.sayHello = function() {
    console.log('Hello ' + name);
};
};
module.exports = Hello;

这样就可以直接获得这个对象了:

//gethello.js
var Hello = require('./hello');
hello = new Hello();
hello.setName('BYVoid');
hello.sayHello();

注意,模块接口的唯一变化是使用 module.exports = Hello 代替了 exports.Hello=Hello。在外部引用该模块时,其接口对象就是要输出的 Hello 对象本身,而不是原先的exports。
事实上,exports 本身仅仅是一个普通的空对象,即 {},它专门用来声明接口,本质上是通过它为模块闭包①的内部建立了一个有限的访问接口。因为它没有任何特殊的地方,所以可以用其他东西来代替,譬如我们上面例子中的 Hello 对象。

警告:不可以通过对 exports 直接赋值代替对 module.exports 赋值。exports 实际上只是一个和 module.exports 指向同一个对象的变量,它本身会在模块执行结束后释放,但 module 不会,因此只能通过指定module.exports 来改变访问接口。

 

可以认为在引用模块的时候,实际上引用的是export对象的属性(属性或者函数)。而在使用module.export声明接口的时候,实际上将export的指向改成了所赋值的对象,此前如果有对export属性的生命(作为接口),在重新定义export指向的对象的时候将全部失效。

 

posted @ 2015-09-14 11:32  流殇微  阅读(206)  评论(0编辑  收藏  举报