(译)Node.js的模块-exports和module.exports

原文标题:Node.js Module – exports vs module.exports
原文连接:http://www.hacksparrow.com/node-js-exports-vs-module-exports.htmlhtml

exports 和 module.exports 有什么区别?

你必定很熟悉 Node.js 模块中的用来在你的模块中建立函数的 exports 对象,就像下面这样。node

建立一个叫作rocker.js的文件:数组

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

而后能够在另一个文件中调用 rocker.js :函数

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

可是,module.exports 到底什么?它是合法的吗?ui

使人吃惊的是:module.exports 是真实存在的。exports 只不过是 module.exports 的帮手而已。你的模块直接返回返回 module.exports 给调用者,而不是 exports 。全部的 exports 作的工做其实是收集属性,若是 module.exports 当前没有任何属性,exports便将收集到的属性添加到 module.exports 上。若是 module.exports
已经存在若干属性,因此 exports 上的属性都会被忽略。this

修改 rocker.js 文件:spa

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

在另外一个文件中调用 rocker.js:翻译

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

上述例子中的 rocker 模块彻底将 exports.name 忽略了,只返回了一个 String 字符串:'ROCK IT!' 。 从这个例子你大概明白了:你的模块并不必定老是一个模块的实例(module instance),它能够是任何合法的 JavaScript 对象——boolean, number, date, JSON, string, function, array 和其余的。你的模块能够是任何你设置的 module.exports 的值。若是你没有明确地为 module.exports 设置任何值,那么 exports 中的属性会自动添加到 module.exports 中,而后并返回它。code

在这种状况下,你的模块时一个类:htm

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 ;若是你只想模块做为一个典型的模块实例(module instance),那么就用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');
};

可是要注意,他们不是同一个东西。就像以前说的同样,exports 只不过是 module.exports 的帮手而已。话虽如此,exports 仍是推荐的对象,除非你想把你模块的对象类型从传统的模块实例(module instance)修改成其余的。

只要你没有使用赋值运算重写 module.exports 对象,任何添加到 module.exports 和 exports 的属性都可以在 require 模块中。

好比这是你的模块中的内容:

module.exports.age = 68;
exports.name = 'Lemmy Kilmister';

下面的代码能够很好的工做:

var rocker = require('./rocker.js');
console.log('%s is %s', rocker.name, rocker.age); // Lemmy Kilmister is 68

可是,若是你在你的模块中重写了 module.exports 中的任何地方,代码便会出错:

module.exports = 'LOL';
module.exports.age = 68;
exports.name = 'Lemmy Kilmister';

或者这样:

module.exports.age = 68;
exports.name = 'Lemmy Kilmister';
module.exports = 'WTF';

顺序没有关系,rocker.age 和 rocker.name 将显示为 undefined。

而且注意:只是由于 module.exports 和 exports 都能输出模块,并不意味这你能够组合使用。个人建议是,坚持使用 exports.*,明白module.exports

我但愿这篇文章能帮助你理解exports和module.exports之间的不一样,而且能进一步的理解模块在Node.js中是怎么工做的。

(完)

翻译水平有待提升,所翻译的博文并非按照原文一句一句翻译,而是添加了本身对文章的理解。若有不正之处,欢迎指正!
我的笔记,仅供参考。

参考:
http://www.hacksparrow.com/node-js-exports-vs-module-exports.html

相关文章
相关标签/搜索