写在前面
Node.js作为JavaScript在服务端的实现,它遵循一套叫common.js的规范。每个模块都有一个全局对象module,同时module对象中有一个对象exports,使用exports对象实现模块导出。exports是module.exports对象的别名,提供便捷的属性和方法设置。
require可以加载文件模块(.js、.code、.json)和nodejs核心模块,最终获取到的是module.exports对象。第一次加载的时候执行代码,第二次从缓存中获取module.exports对象,如果没有发现指定模块就报错not find module。
模块标识可以不包含后缀名,所以Node.js在文件定位时会依次补充.js,.json,.node后缀名,然后去进行文件定位,因为Node.js是单线程,所以文件定位时会发生堵塞,所以如果引入的模块后缀是.json或者.node,可以在引入的时候加上后缀,可以提高查找速度。
关键字:
exports 导出
require 导入
模块
一个js就是一个模块,本模块内声明的变量,常量,函数,默认在外(其他模块)是无法读取的,需要在本模块导出,其他模块导入。
模块上下文提供了exports
对象用于导入导出当前模块的方法或者变量,并且它是唯一的导出出口。模块中存在一个module
对象,它代表模块自身,exports
是module的属性。一个文件就是一个模块,将方法作为属性挂载在exports上就可以定义导出的方式:
导出模块写法
#### 第一种写法:
exports是一个对象,初始值是空对象,存导出的内容
exports.a = a; //导出常量a
exports.fn = fn; //导出函数体
log(exports); //{ a: 12 };
//注意用:exports导出的内容可以以时一个除非空对象外的任意数据类型,当对象内含有属性方法时,用exportx导出的对象是一个空对象
###第二种写法: modele.exportx
它和exports是等价的,exports是他的简化写法
当两者都同时存在,且mudole.exports右边是一个对象形式时,以mudole.exports内容为准
即会覆盖exports里的内容
①: module.exports = {
num: 0,
count() {
log(this, this.num) //undefined
this.num++;///每次调用该方法,num值+1
console.log(this.num);
}
}
**//问题:导入后直接用对象名调用和解构赋值,this指向不同,调用方法时打印的num值为初始值0
**//解决方案:①:不使用this指向,或者直接用module.exports代替this指向
②: 变量单独声明在外, 只导入1个, 避免使用this
let num = 0;
let count = () => {
num++;
log(num)
}
module.exports = { num, count }
③:在导出时使用用call,apply,bind,来改变this的指向,让this指向 导出对象module.expots
导入模块写法:
模块标识就是传递`给require()`方法的参数,它必须是符合小驼峰命名的字符串,或者以`.`、`..`开头的相对路径或者绝对路径,可以没有文件后缀名`.js`.
可导入任意数据类型,文件夹目录
const A = require('文件路径');
使用被导入页面的数据:
console.log(A)
A.fn()//函数调用
A.count()//调用导入对象里面的对象里面的方法。
###注意://①重复导入,原来模块会并且只会执行一遍
//②导入一个模块,会先执行一遍该模块代码
##导入导出数据重名问题的解决:
//在导入的module.expots的写法不变时,结构赋值调用时可以
//const { x: y } = require('./index.js');---此时打印y所得就是x的属性值
##默认入口文件问题:
// ①导入的是默认的入口文件,test目录下的index.js ,如果没有即报错
// ②修改package.json里的入口文件名。即main的值
#模块间是否相互导入数据共享??