NodeJs中Module.exports和exports

时间:2022-05-12 23:13:41

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;
};


官方文档中的另一段话:

引用
As a guideline, if the relationship between exports and module.exports seems like magic to you, ignore exports and only use module.exports.
当你对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。

引用
The exports variable that is available within a module starts as a reference to 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中创建对象有多种方式。

引用
《JavaScript高级程序设计(第3版)》第6章第2节


我们使用其中介绍的第三种方式——原型模式来创建一个对象

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的。