Node.js(笔记06) - 模块化
什么是模块化
遵守固定的规则,把一个大文件拆成独立并互相依赖的多个小模块。
代码模块化的优势:
1)提高代码的复用性;
2)提高代码的可维护性;
3)可以实现按需加载;
模块块规范是:对代码模块化拆分和组合时,遵守的规则;
1)引用模块;
2)暴露接口;
Node.js 模块分类
1)内置模块:由Node.js官方提供的,如: fs、path 和 http 模块;
2)自定义模块:用户自己创建的 js 文件;
3)第三方模块:第三方开发的,使用前需下载;
加载模块
使用 require() 方法,加载需要的内置模块、自定义模块和第三方模块;
引入模块,代码示例:
注意1:使用 require() 方法加载其他模块时,会执行被加载模块中的代码;
注意2:使用 require() 方法加载自定义模块时,扩展名 .js 可以省略;
写个文件 test.js ,并保存到 "./files/" 目录下:
在 demo.js 文件引入:
提示:引入模块的时候可以省略 js ;
终端输出:
可以执行,还多了一个空对象 {} ,后面再说;
模块作用域
和函数作用域类似,在自定义模块中定义的变量、方式等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域;
也就是说,在test.js 中定义的常量, 在被引用时不能输出;
模块作用域的好处:防止了全局变量污染的问题;
共享模块作用域中的成员
module 对象
在每个自定义模块中,都会包含 module 对象,里面存储了和当前模块有关的信息。
新建个 js 文件,输出 module 看下:
module.exports 对象
在自定义模块中,使用 module.exports 对象,将模块内的成员共享出去,供外界使用;外界用 require() 方法引入自定义模块时,得到的就是 module.exports 所指向的对象。
提示:在自定义模块中,默认情况下 module.exports={} ,这就解释了,之前为什么会输出空对象了;
使用 module.exports 对象就可以共享属性和方法:新建 m1.js
在 demo.js 中引入 m1.js 自定义模块:
终端输出:
修改 m1.js 并共享一个常量:
再看下终端输出:
共享成员时注意点
使用 require() 方法导入模块时,导入的结果,永远以 module.exports 指向的对象为准。
示例说明:
提示:这里让 module.exports 直接指向了新的对象;
再执行一下 demo.js:
提示:输出为新的对象;
提示:指向新对象后,再给新对象追加属性和方法呢?就又都有了;
示例说明:
提示:仅仅是把代码换回到下面,意思是在新对象后又追加了属性和方法:
看下终端输出:
exports 对象
由于 module.exports 单词写起来比较复杂,为了简化向外共享代码,Node提供了 exports 对象。默认情况下, exports 和 module.exports 指向同一个对象。最后共享的结果,还是以 module.exports 指向的对象为准。
示例说明:
看下终端的比较结果:
说明这两个对象指向的是同一个对象;
所以之前的代码可以简定:
等效于:
共享成员使用误区
require() 引入模块时,得到的永远是 module.exports 指向的对象:
误区一
module.exports 指向了新的对象,并以 module.exports 指向的对象为准;
即使使用 exports 追加也不行,只能使用 module.exports 追加才可以;
提示:随着 module.exports 另外指向了对象,原来的 exports 无效了;
误区二
这次是用 exports 来指向新对象了,结果又如何呢?
示意图:
所以,再次验证了 module.exports 所指向的对象优先级高;
误区三
这次得到的 module.exports 对象有几个属性呢?
是两个,因为对象没有变,指向是同一个对象;
误区四
提示:exports 和 module.exports 都指向了新的对象,所以引入的模块有三个属性;
示意图:
注意:为了防止混乱,不要在同一个模块中同时使用 exports 和 module.exports ,即使混用了,也要知道引入的模块的对象,最终都是 module.export 指向的对象。
CommonJS 规范
Node.js 遵循了 CommonJS 模块化规范,CommonJS 规定了 模块的特性 和 各模块之间如何相互依赖。
CommonJS 规定:
1)每个模块内部, module 变量代表当前模块;
2)module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口;
3)加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块;