JS的模块化开发
- 高级单例设计模式:创建一个命名空间,接收闭包中返回的信息,然后把闭包的内容暴露出去,这样闭包中的内容就会暴露出去供闭包外面的内容调用
let module1=(function(){
let n=1;
function query(){
return n
}
function fn(){
return n+1
}
return {
query,
fn
}
})()
let module2=(function(){
function fn(){
return true
}
//这里调用了module中的方法
module1.query()
return {
fn
}
})()
let wetherModule = (function () {
function query(){
return falase
}
function func(){
return true
}
return {
init() {
// ...按照业务顺序逐一加载对应的方法
query();
func();
}
}
})();
wetherModule.init();
- AMD 模块化思想:最早的模块化思想,定义的时候用define定义,让后调用的时候用require调用(了解即可)
- 实现sun的求和和average求平均值
//导入
<script src="./js/require.min.js"></script>
<script src="./main.js"></script>
//moduleA.js===>定义
define(function() {
let sum = function sum(...arg) {
if (arg.length === 0) return 0;
if (arg.length === 1) return arg[0];
return arg.reduce((pre, next) => {
return pre + next
}, 0)
}
return { sum }
})
//moduleB.js====》定义
define([
"js/moduleA.js"
], function(moduleA) {
let average = function average(...arg) {
debugger
if (arg.length === 0) return 0;
if (arg.length === 1) return arg[0];
return (moduleA.sum(...arg) / arg.length).toFixed(2)
}
return { average }
})
//main.js===》使用
require([
"js/moduleB.js"
], function(moduleB) {
console.log(moduleB.average)
let result = moduleB.average(10, 20, 30, 40, 50, 60, 70);
console.log(result)
})
- 自己简单实现 AMD 源码
let factories = {};
let define = function define(moduleName, dependency, factory) {
if (typeof dependency === "function") {
factory = dependency;
}
factories[moduleName] = factory;
if (typeof dependency === "array") {
let keys = Object.keys(factories);
dependency = dependency.map((item) => {
if (keys.includes(item)) {
return factories[item]();
}
return new Error("您还未添加!");
});
factory(...dependency);
}
};
let require = function require(dependency, callback) {
dependency = dependency.map((item) => {
return factories[item]();
});
callback(...dependency);
};
define("moduleA", function () {
return {
fn() {
console.log("moduleA");
},
};
});
define("moduleB", function () {
return {
fn() {
console.log("moduleB");
},
};
});
require(["moduleA", "moduleB"], function callback(moduleA, moduleB) {
moduleA.fn();
moduleB.fn();
});
-
CMD 模块化设计思想:node常用的模块导入和导出方式.require 导入模块,module.exports 导出模块中的方法
-
ES6Module 模块化思想:es6新增的新特性.import 导入模块,export/export default 导出模块中的方法
CMD 和 ES6Module 的区别:
-
CommonJS 是运行时加载
-
ES6Module(在项目中一般配合 webpack 来使用)是在编译时处理
8 种高级单例设计模式
- 高级单例设计模式:创建一个命名空间,来管理某一个模块中的内容,并且可以把模块的内容暴露出去,实现模块之间的独立划分「但是也可以实现模块之间方法的相互调用」
let SearchModule = (function () {
let body = document.body;
function queryData() {}
function bindHTML() {}
function handle() {}
return {
// init相当于大脑,可以控制谁先执行,谁后执行 「命令模式」
init: function () {
queryData();
bindHTML();
handle();
}
};
})();
SearchModule.init();
let AModule = (function () {
let arr = [];
let change = function change(val) {
arr.push(val);
console.log(arr);
};
return {
change: change
};
})();
AModule.change(10);
AModule.change(20);
- constructor 构造器设计模式(之前的插件组件封装常用)
class AModule {
constructor() {
// this->每个类的实例
this.arr = [];
}
// 原型上 公共的属性和方法
change(val) {
this.arr.push(val);
console.log(this.arr);
}
}
let A1 = new AModule();
let A2 = new AModule();
console.log(A1, A2);
console.log(A1 === A2); //->false
console.log(A1.arr === A2.arr); //->false
console.log(A1.change === A2.change); //->true
A1.change(10);
A2.change(20);
- Factory 工厂模式(JQ工厂模式)
function factory(options) {
options = options || {};
let { type, payload } = options;
if (type === "array") {
// 执行A,完成一个逻辑
return;
}
// 执行B,完成另外的逻辑
}
factory({
type: "array",
payload: 100,
});
factory({
type: "object",
payload: "zhufeng",
});
-
Observer [əbˈzɜːrvər]观察者模式:
- 每个观察者应该具备update方法,用于通知消息,到达的时候,进行相关处理
- 目标:管理观察者(增删改查)及通知消息处理的能力
//1.创建n个观察者:有个方法,用于通知消息到达的时候,进行相关的出来 class observer { update(message) { console.log("消息接收!", message); } } class demo { update(message) { console.log("消息接收!", message); } } //2.创建一个观察者列表,管理观察者(进行增删改查和通知观察者方法执行) class subjecList { constructor() { this.observeList = []; } add(observer) { this.observeList.includes(observer) ? null : this.observeList.push(observer); return this; } remove(observer) { this.subjecList.filter((item) => item !== observer); return this; } get(index) { return this.observeList[index]; } count() { return this.observeList.length; } } //3.创建一个目标类,里面可以进行增删改查和通知方法执行 class subject { observe = new subjecList(); //可以调用subjecList的方法 add(observe) { this.observe.add(observe); } remove(observe) { this.observe.remove(observe); } notify(...args) { for (let i = 0; i < this.observe.count(); i++) { let item = this.observe.get(i); item.update(...args); } } } let sub = new subject(); sub.add(new observer()); sub.add(new observer()); sub.add(new demo()); setTimeout(() => { sub.notify("你好~~欢迎大家报名珠峰培训在线web高级!"); }, 1000); -
Mediator [ˈmiːdieɪtər]中介者模式
let mediator = (function () {
let topics = {};
//1.订阅
let subscribe = function subscribe(topic, callback) {
topics[topic] = !topics[topic] ? [] : null;
topics[topic].push({
context: this,
callback: callback,
});
};
//2.发布
let publish = function publish(topic, ...args) {
if (!topics[topic]) return;
topics[topic].foreach((item) => {
let { context, callback } = item;
callback.call(context, ...args);
});
};
return {
subscribe,
publish,
};
})();
- 发布订阅模式
(function () {
const hasOwn = Object.prototype.hasOwnProperty;
class Sub {
constructor() {
//pond={a:[],b:[]}
this.pond = {};
}
$on(type, func) {
let arr;
//先查看pond有无事件,若无,添加事件,若有,直接加方法
let pond = this.pond;
!hasOwn.call(pond, type) ? (pond[type] = []) : null;
arr = pond[type];
!arr.includes(func) ? arr.push(func) : null;
}
$off(type, func) {
let pond = this.pond,
arr = pond[type];
if (!arr) return;
for (let i = 0; i < arr.length; i++) {
arr[i] = null;
}
}
$emit(type, ...params) {
let pond = this.pond,
arr = pond[type];
let func = null;
if (!arr) return;
for (let i = 0; i < arr.length; i++) {
func = arr[i];
if (typeof func !== "function") {
arr.splice(i, 1);
i--;
}
arr[i](...params);
}
}
}
//直接暴露方法
let sub = new Sub();
["$on", "$off", "$emit"].forEach((item) => {
window[item] = function anonymous(...arg) {
return sub[item](...arg);
};
});
})()