Node应用由模块组成,采用CommonJS模块规范。javascript
根据这个规范,每一个文件就是一个模块,有本身的做用域。在一个文件里面定义的变量、函数、类,都是私有的,对其余文件不可见。java
CommonJS规范规定,每一个模块内部,module变量表明当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,实际上是加载该模块的module.exports属性。app
上面代码经过module.exports输出变量x和函数addX。函数
require方法用于加载模块。工具
语法:ui
做用:spa
一、执行被加载模块中的代码code
二、获得被加载模块中的exports导出接口对象对象
Node中是模块做用域,默认文件中全部的成员只在当前文件模块有效。接口
对于但愿能够被其它模块访问的成员,咱们就须要把这些公开的成员都挂载到exports接口对象中就能够了。
1. 导出多个成员(必须在对象中)
2. 导出单个成员
错误写法1
错误写法2
若是一个模块须要直接导出某个成员,而非挂载的方式,那这个时候必须使用下面这种方式
结果:
只有一个module.exports时,无论是在位置一仍是位置二,都为 bar。
当有两个module.exports 时,好比一个在位置一,另外一个在位置三,会导出位置三的对象(module.exports会被后者覆盖)。
上面的结果出现的缘由:exports 和module.exports是有区别的。
在Node中,每一个模块内部都有一个本身的module 对象,该 module 对象中,有一个成员叫exports也是一个对象,相似这样:
每次导出的对象是module.exports,若是你须要对外导出成员,只须要把导出的成员挂载到module.exports中。
也就是说module.exports才是真正的接口,exports只不过是它的一个辅助工具。最终返回给调用的是module.exports而不是exports。
为了方便,Node为每一个模块提供一个exports变量,指向module.exports。这等同在每一个模块头部,有一行这样的命令:
exports至关因而 一个引用,指向module.exports对象,因此有
因而咱们能够直接在 exports 对象上添加方法,表示对外输出的接口,如同在module.exports上添加同样。注意,不能直接将exports变量指向一个值,由于这样等于切断了exports与module.exports的联系。
同理,给 module.exports 从新赋值也会断开。
可是这里又从新创建二者的引用关系:
最后,必定要记得return的是module.exports。
若是给exports赋值,断开了两个引用之间的联系,就无论用了。
若是要对外暴露属性或方法,就用 exports 就行,要暴露对象(相似class,包含了不少属性和方法),就用 module.exports。