Nodejs中module.exports和exports区别

454 查看

最近小组一个大神搭建了一套基于webpack + gulp的框架,表示不明觉厉,然后接到一个需求要在这个框架里面做开发,于是边模仿边请教大神,也算是搞定了。但是作为一个刚转前端的小菜,虽然可以完成功能,对于整个框架的原理还是一知半解,不开心~ ~所以从基础学起,开始学习Node.js咯。

Node.js中暴露引入接口使用exports/require,使用起来还挺方便,但是module.exports和exports好容易混淆,有时引入时还会莫名其妙地报错,纠结了半天终于搞懂两者的区别了。

Node.js在模块编译过程将模块包装成一个闭包,最终返回类似这样的代码:

(function (exports, require, module, __filename, __dirname) {
    // module code...
});

其中,module是模块本身,它跟exports的关系是:

exports = module.exports = {};

可以看出,exports和module.exports指向同一个对象,而require引用模块后,返回给调用者的是module.exports,这就出现两种情况了:
1、暴露属性/方法,使用exports是没有问题的:

exports.attr = "attr";
exports.fn = function(){};

原因是exports和module.exports指向同一个对象,上面两行代码都是exports为一起指向的那个对象添加属性,使用require后返回module.exports也会被更改。当然,直接使用module.exports暴露属性/方法也是可以的。

2、暴露一个类,要使用module.exports:

var obj = function(){};
module.exports = obj;

如果使用exports = obj是无法require到这个类的,原因是这相当于让exports去指向别的对象了,关module.exports啥事,module.exports还是老老实实地指向原来那个对象,没变,所以require后,返回的module.exports自然得不到obj。

哈哈,我记得java里内存管理中栈和堆就是这么解的,类比~