详解Node.js中exports和module.exports的区别

首先我们先看个例子

var a = {name:1};
var b = a;
console.log(a);
console.log(b);
b.name =a;
console.log(a);
console.log(b);
var b = {name:3};
console.log(a);
console.log(b);
运行结果为:
{name:1}
{name:1}
{name:2}
{name:2}
{name:2}
{name:3}

解释:a是一个对象,b是对a的引用,即a和b指向同一块内存,所以前两个输出一样。当对b做修改时,即a和b指向同一块内存地址的内容发生了改变,所以a也会体现出来,所以第三四个输出一样。当b被覆盖时,b指向了一块新的内存,a还是指向原来的内存,所以最后两个输出不一样。
同理 exports和module.exports 也是这个道理
exports 和module.exports 初始值指向的是空对象,即{}。从源码可以看到,其实模块的require方法实质上是调用了_load方法,而_load方法,最终返回的是module.exports。
通过下面两个小案例我们可以区分他们之间的关系。

  • 方式一:用exports
//a.js
 
 exports.log =function (str) {
  console.log(str);
}
//b.js
 
 var s = require("./a");
 s.log("哈哈哈哈");
  • 方式二:用module.exports
//a.js
 module.exports = function (str) {
    console.log(str);
 }
//b.js
 var s = require("./a");
 s("嘻嘻嘻嘻");

由于最开始的时候,exports和module.exports都指向同一个对象。
第一种方式,是在给这个空对象{}添加属性,又因为module.exports也是指向这个对象的,所以最终require方法返回的module.exports是指向了这个具有log方法的对象的,可以引用到模块。
第二种方式是让module.exports指向一片新的内存空间,exports指向的仍然是{},但是由于require方法返回的是module.exports,所以最终也能引入模块。
请牢记:require方法返回的是module.exports!

猜你喜欢

转载自blog.csdn.net/literarygirl/article/details/89467144
今日推荐