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 是被推荐的对象,除非你想改变你的模块的对象类型,例如从传统的对象实例变为其他的东西。
我希望这篇文章能够帮助你理解
exports
和 module.exports 之间的不同,并且学习一点儿关于模块在Node.js是怎么工作的,如果有其他问题,请留言。
总结
我个人的理解就是:
一、在一个模块或者文件中如果你事先用了 module.exports 然后再用 exports 的话exports导出的属性会被覆盖
二、使用 module.exports 可以导出任何经典对象 boolean, number, date, JSON, string, function, array
三、module.exports.name 的用法和 exports.name 是一样的
译言
本人的英语不好,大部分地方算是直译吧,所以比较差,只是想抛砖引玉,感兴趣的童鞋可以看看原文。本人读完了解的也只是皮毛,还希望大虾们能有更详细的解释。