什么是模块化?
模块化是指解决一个问题时,自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说,模块是可组合,可分解可更换的单元
模块化的好处
1·提高代码的复用性
2·提高代码的可维护性
3·可以实现按需加载
nodejs模块分类
内置模块(由node官方提供
自定义模块(用户创建的每个.js文件都是自定义模块
第三方模块(由第三方开发出来的模块,不是官方提供也不是用户创建,使用前需要先下载
简单模块
/* index.js */
//自定义模块时,提供路径,路径可以省略后缀名
const myModule = require('./myModule')
console.log(myModule) //输出:加载了用户自定义模块文件\n{}
/* myModule.js */
//用户自定义模块文件
const log = '加载了用户自定义模块文件'
console.log(log)
模块作用域
什么是模块作用域
和函数作用域类似,在自定义模块中定义的方法和变量等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域
模块作用域的好处
防止全局污染问题
向外共享作用域中成员
module 对象
每个.js自定义模块都有一个module对象,他里面储存了和当前模块有关的信息,打印如下:
module 对象
module.exports对象
在自定义模块中,可以使用module.exports对象,将模块内成员共享出去,供外界使用
外界用require()方法导入自定义模块时,得到的就是module.exports所指的对象
/*
index.js
自定义模块中,默认情况下,module.exports={}
在外界使用require方法导入一个自定义模块的时候,
得到的成员就是那个模块中module.exports所指向的对象
*/
const m = require('./testModule')
console.log(m)
/*
testModule.js
*/
const userName = 'kk'
//向module.exports对象上挂载userName属性和seyHi方法
module.exports.userName = userName
module.exports.sayHi = function () {
console.log('Hi! my name is', userName)
}
打印如下:
向外共享作用域中成员演示
注意:
使用require()方法导入模块时,导入的结果,永远以module.exports指向的对象为准
/*
index.js
*/
const m = require('./testModule')
console.log(m)
/*
testModule.js
*/
const userName = 'kk'
const age = '18'
//向module.exports对象上挂载userName属性和seyHi方法
module.exports.userName = userName
module.exports.sayHi = function () {
console.log('Hi! my name is', userName)
}
//module.exports指向全新的对象
module.exports = {
nickName: '莉莉',
age: '20',
sayHello() {
console.log('Hello')
},
}
module.exports指向
exports对象
默认情况下exports对象和module.exports对象指向同一个对象
(exports==module.exports)最终共享的结果还是以module.exports指向的对象为准
//index.js
const m = require('./testModule')
console.log(m)
//testModule.js
const userName = 'kk'
const age = '18'
//向module.exports对象上挂载userName属性和seyHi方法
exports.userName = userName
exports.age = age
exports.sayHi = function () {
console.log('Hi! my name is', userName)
}
exports对象
module.exports与exports
//index.js
const m = require('./testModule')
console.log(m)
// testModule.js
/*
默认情况下exports和module.exports指向同一个对象
当直接给exports赋值(exports={})时,两个将不指向同一对象
*/
//? =======================================================================================================
//module.exports对象上挂载
module.exports.name = '坤坤'
//向exports对象上挂载userName属性和seyHi方法
//这个直接赋值会改变指向!达咩!
exports = {
userName: '莉莉',
sayHello() {
console.log('Hello')
},
}
//! 上面输出{ name: '坤坤'}
/*
因为exports = {}改变了指向
a={}//开始的对象
b=a//module.exports
c=a//exports
这是最开始的情况
当我们给c.name这样赋值,不会改变c的指向,而当c={}就已经改变了c的指向,他不在指向a
*/
exports 案例1.png
//index.js
const m = require('./testModule')
console.log(m)
// testModule.js
//? =======================================================================================================
module.exports = {
userName: '莉莉',
sayHello() {
console.log('Hello')
},
}
exports.userName = '坤坤'
//!打印:{ userName: '莉莉', sayHello: [Function: sayHello] }
/*
同样
a={}//开始的对象
b=a//module.exports
c=a//exports
这是最开始的情况
当b不在指向a时,c指向a,b!=c了,b和c直接不指向同一对象
*/
exports案例2.png
exports 案例3.png
exports 案例4.png
建议不要在同一模块中即使用exports又使用module.exports,以防混乱
nodejs中的模块化规范
nodejs遵循了CommonJS模块化规范,commonJS规定了模块的特性和各模块之间如何互相依赖
CommonJS规定
1.每个模块内部,module变量代表当前模块
2.module变量是一个对象,它的exports属性(即module.exports)是对外的接口
3.加载某个模块,其实是加载该模块的module.exports属性。require()方法用于加载模块