【NodeJS】浅析 exports 和 module.exports

来源:互联网 发布:知世公主 编辑:程序博客网 时间:2024/05/18 03:18

  exports 和 module.exports 的作用都是将文件模块的方法和属性暴露给 require 返回的对象进行调用。但是二者之间存在本质的区别。

  exports 的属性和方法都可以被 module.exports 替代,如下面的代码,其作用都是一致的。

exports.name = 'bob'module.exports.name = 'bob'

  但 exports 不能替代 module.exports 方法,可以理解为包含关系。所有的 exports 对象最终都是通过 module.exports 传递执行,因此可以更确切地说,exports 是给 module.exports 添加属性和方法。为了验证这一点,我们将文件中的 module.exports 对象打印出来与 exports 方法和属性进行对比,代码如下:

/* test.js */exports.name = 'a';exports.happy = function(console.log('happy'));console.log(module.exports);// 运行结果:{ name: 'a', happy: [Function] }

  从结果中可以看出,module.exports 相当于 require 返回的对象,也就是所有 require 返回的对象,实质上结果和 module.exports 是相同的。这里我们可以做个检测,常见一个index.js文件,代码如下:

/* index.js */var obj = require('./test.js');console.log(obj);/* 运行结果: { name: 'a', happy: [Function] } { name: 'a', happy: [Function] }*/

  module.exports 方法还可以单独返回一个数据类型,而 exports 只能返回一个 object 对象。当我们需要返回一个数组、字符串、数字等的类型时,就必须使用 module.exports。
  
  module.exports才是真正的接口,exports只不过是它的一个辅助工具。 最终返回给调用的是module.exports而不是exports。所有的exports收集到的属性和方法,都赋值给了Module.exports。当然,这有个前提,就是module.exports本身不具备任何属性和方法。如果,module.exports已经具备一些属性和方法,那么exports收集来的信息将被忽略。请看下例:

/* test.js */exports.a = function(){    console.log('a')}module.exports = {a: 2}exports.a = 1
/* index.js */var obj = require('./test');console.log(obj.a);/* 运行结果:2 */

说明exports在module.exports 被改变后,失效。


CommonJS规范

  这种模块加载机制被称为 CommonJS 规范。在这个规范下,每个.js文件都是一个模块,它们内部各自使用的变量名和函数名都互不冲突,例如,hello.jsmain.js都申明了全局变量var s = 'xxx',但互不影响。
  
  一个模块想要对外暴露变量(函数也是变量),可以用module.exports = variable;,一个模块要引用其他模块暴露的变量,用var ref = require('module_name');就拿到了引用模块的变量。

原创粉丝点击