exports 与 module.exports 的区别

exports与module.exports的作用就是将方法或者是变量暴露出去,以便给其他模块调用,再直接点,就是给其他模块通过require()的方式引用。

那么require()一个模块时,到底做了什么呢?下面大概展现了require()的伪代码实现:

function require(/* ... */) {
  const module = { exports: {} };
  ((module, exports) => {
    // Module code here. In this example, define a function.
    // function someFunc() {}
    // exports = someFunc;
    // At this point, exports is no longer a shortcut to module.exports, and
    // this module will still export an empty default object.
    // module.exports = someFunc;
    // At this point, the module will now export someFunc, instead of the
    // default object.
  })(module, module.exports);
  return module.exports;
}

由此可以看出:

  • module.exports默认指向一个空对象{}
  • exports在默认情况下是指向module.exports的引用
  • require()返回的是module.exports而不是exports

所以,如果是通过exports.test = function() {} 的形式暴露出去,无论是使用exports还是使用module.exports,在功能上并没有什么差别;但是如果是通过exports = function() {} 的形式暴露出去,结果往往会出乎意料。从伪代码中可知,exports对象是通过形参的方式传入的,直接赋值形参会改变形参的引用,但是不会改变作用域外的值,也就是说module.exports原来的值是什么,现在还是什么,不会有任何改变,而require()方法最终返回的是module.exports,所以结果可想而知。

// 文件1.js
exports = function () {
    console.log('exports')
}

// 文件2.js
var test = require('./1');
console.log(test); // 结果是module.exports的默认值,也就是空对象{}
posted @ 2017-11-15 23:22  大炮~  阅读(327)  评论(0编辑  收藏  举报