Node.js Module – exports vs module.exports

原文:http://www.hacksparrow.com/node-js-exports-vs-module-exports.html

译文

在Node.js中 exports 和 module.exports 有什么不同呢?

在Node.js的 module 中想必你已经对 exports 这个对象已经比较了解了,它用于你在你的模块中创建一个函数,像下面的例子一样(假设在一个叫rocker.js的文件中):

exports.name = function() {
    console.log('My name is Lemmy Kilmister');
};

然后你从另一个地方调用它:

var rocker = require('./rocker.js');
rocker.name(); // 'My name is Lemmy Kilmister'

但是奇怪的是 module.exports,它是否是一样的用法呢?

令人惊奇的是 module.exports 是一个真正的协议。exports 仅仅是 module.exports 的一个小助手。你的模块返回 module.exports 给一个调用者,而不是 exports。所有的 exports 集合属性并且把它们附加到 module.exports 假如 module.exports 还没有其他的东西存在。如果已经有其他的东西被附加到 module.exports ,那么在 exports 的所有东西将被忽略。

把下面的代码放入 rocker.js文件:

module.exports = 'ROCK IT!';
exports.name = function() {
    console.log('My name is Lemmy Kilmister');
};

这是另一个文件,运行它:

var rocker = require('./rocker.js');
rocker.name(); // TypeError: Object ROCK IT! has no method 'name'

rocker模块完全忽略了 exports.name ,并且返回了一个字符串 'ROCK IT!'。从这个例子你大概已经了解到了你的模块并非是不得不成为'module instances'(模块示例)。你的模块可以是任意的javascript对象,例如boolean, number, date, JSON, string, function, array等等。无论怎样你的模块都是需要设置 module.exports 的,假如你不明确的设置 module.exports 给任何的事物,exports 的属性将要附加到它上面并且返回。

在这个例子中,你的模块是一个类:

module.exports = function(name, age) {
    this.name = name;
    this.age = age;
    this.about = function() {
        console.log(this.name +' is '+ this.age +' years old');
    };
};
并且你这样调用它:
var Rocker = require('./rocker.js');
var r = new Rocker('Ozzy', 62);
r.about(); // Ozzy is 62 years old

在这个例子中,你的模块是一个数组:

module.exports = ['Lemmy Kilmister', 'Ozzy Osbourne', 'Ronnie James Dio', 'Steven Tyler', 'Mick Jagger'];

你这样调用它:

var rocker = require('./rocker.js');
console.log('Rockin in heaven: ' + rocker[2]); //Rockin in heaven: Ronnie James Dio

到这里你应该知道重点所在了——假如你的模块特殊的对象类型,那么用 module.exports;假如你的模块是一个典型的模块实例,那么用 exports。

附加属性到 module.exports 意味着附加属性到 exports,例如:

module.exports.name = function() {
    console.log('My name is Lemmy Kilmister');
};
这和下面的代码所实现的意义是一样的:
exports.name = function() {
    console.log('My name is Lemmy Kilmister');
};

但是注意,它们不是一样的。正如我之前说的一样 module.exports 是真正的协议, exports仅仅是一个小助手。并且还说过,exports 是被推荐的对象,除非你想改变你的模块的对象类型,例如从传统的对象实例变为其他的东西。

我希望这篇文章能够帮助你理解 exportsmodule.exports 之间的不同,并且学习一点儿关于模块在Node.js是怎么工作的,如果有其他问题,请留言。

总结

我个人的理解就是:

一、在一个模块或者文件中如果你事先用了 module.exports 然后再用 exports 的话exports导出的属性会被覆盖

二、使用 module.exports 可以导出任何经典对象 boolean, number, date, JSON, string, function, array

三、module.exports.name 的用法和 exports.name 是一样的

译言

本人的英语不好,大部分地方算是直译吧,所以比较差,只是想抛砖引玉,感兴趣的童鞋可以看看原文。本人读完了解的也只是皮毛,还希望大虾们能有更详细的解释。

posted @ 2012-06-25 13:42  DolphinBoy  阅读(421)  评论(0编辑  收藏  举报