commonJS模块导出
1.module.exports 和exports
commonJS规范
- 一个js文件就是一个模块
- 模块内所有的变量均为局部变量,不会污染全局
- 模块中需要提供给其他模块使用的内容需要导出
- 导出使用
exports.xxx = xxx或module.exports=xxx - 其他模块可以使用
require函数导入 - nodejs实现了commonJs规范,浏览器环境无法使用module.exports
- Node中每个模块都有一个module对象,module对象中有一个exports属性为一个接口对象,我们把模块之间的公共的方法或者属性挂载在这个接口对象中,方便其他模块使用这些公共的方法或者属性。
- exports是 module.exports的简写形式.
- Node中每个模块的最后,都会return:module.exports。
- module.exports = xxx,表示当前模块导出一个单一函数,一个对象,也可以是一个类。
- 如果需要导出多个成员变量时,使用exports.add = xxx; exports.foo = xxx; 或者使用 module.exports.add = xxx; module.exports.foo = xxx;
2.同时导出普通函数和类(构造函数)
把构造函数当成对象的属性导出
module.exports = {
pushTarget, popTarget, Dep
}
ES6解构的方式进行导入, 这样就可以使用new Dep() 创建类的实例了
const { Dep } = require("./dep.js");
模块dep.js内容如下
let id=0;
class Dep {
constructor(){
this.id = id++;
this.subs = [] // 存放watcher
}
depend(){
if(Dep.target){
Dep.target.addDep(this) // 把自身-dep实例存放在watcher里面
}
}
notify(){
// 依次执行subs里面的watcher更新方法
this.subs.forEach((watcher) => {
watcher.update()
})
}
// 把watcher加入到自身的subs容器
addSub(watcher){
this.subs.push(watcher)
}
}
// Dep.target 是一个全局 Watcher 指向 初始状态是 null
Dep.target = null;
// 栈结构用来存watcher
const targetStack = []
function pushTarget(watcher) {
targetStack.push(watcher);
Dep.target = watcher; // Dep.target指向当前watcher
}
function popTarget(){
targetStack.pop(); // 当前watcher出栈 拿到上一个watcher
Dep.target = targetStack[targetStack.length -1]
}
module.exports = {
pushTarget, popTarget, Dep
}