Node.js中的什么时候用module.exports,什么时候用exports,区别是什么
官方文档的一开头,给出的例子是这样的:
http://nodejs.org/api/modules.html
var circle = require('./circle.js'); console.log( 'The area of a circle of radius 4 is ' + circle.area(4));
var PI = Math.PI; exports.area = function (r) { return PI * r * r; };
官方文档中的另一段话:
当你对module.exports和exports的关系感到困惑的时候,一直使用module.exports,并且忽略exports
于是问题出来了,module.exports是怎么回事儿?我们什么时候使用module.exports,什么时候使用exports呢?
如果你的模块属于“模块实例(module instances)”,就像官方文档中给出的示例那样,那么exports足以满足要求。
但是事实上,require()返回的是module.exports,exports只是module.exports的一个引用,exports的作用只在module.exports没有指定的时候,收集属性并附加到module.exports。
你的模块总是返回module.exports,而不是exports。
module.exports = '孙悟空'; exports.name = function() { console.log('我是白骨精'); };
这个模块会完全忽略exports.name,因为module.exports被指定了另一个对象。你的模块不一定是模块实例(module instances),你的模块可以是任意的,你设置成module.exports的Javascript对象。如果你不显示的指定module.exports,那么返回的将是exports和exports附加的值。
也可以这样认为,一个模块刚开始的时候,module.exports和exports是一样的,exports只是module.exports的一个别名,两者都是{}。
当你给module.exports指定一个对象的时候,两者就不再一样的,而模块导出的一定是module.exports。
如果你想你的模块是指定的一种对象类型,那就使用module.exports,如果你想让你的模块是典型的模块实例,那就用exports就可以了。
下面介绍一种module.exports的典型用法,将模块导出来类或者对象。
在Javascript中创建对象有多种方式。
我们使用其中介绍的第三种方式——原型模式来创建一个对象
function Person(){ } Person.prototype.sayName = function(){ console.log('我叫唐僧'); }; module.exports = new Person();
在其他代码中require引用此模块时,将返回一个Person的对象,并调用其中的方法。
var person = require('./person'); person.sayName();
当然也可以用
module.exports = Person;
导出Person,在需要时候使用
var Person = require('./person'); var person = new Person(); person.sayName();
来创建对象。
这个东西其实类似:
var o = { a: 1}, b = o, c = { b: 2}; b;// {a:1} b = c; b;//{b:2} o;//{a:1}
赋值不会改变引用参数,即对b赋值,无论何值,o不受影响,但改变b的属性,o就受影响了,exports和module.exports就这么一个意思,对exports赋值,无法影响module.exports的值,但对exports.xxx赋值可以,对module.exports赋值,则可以覆盖exports。因为exports是指向module.exports的。