原文标题:Node.js Module – exports vs module.exports
原文连接:http://www.hacksparrow.com/node-js-exports-vs-module-exports.htmlhtml
你必定很熟悉 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