单例设计模式
都写在全局下,会存在全局变量污染的问题 基于闭包的方式解决全局污染的问题 [无法直接调用其他模块下的方法]
- window.xxxx = xxx; 暴露的API不易过多
- 基于对象分组的特点: 把当前需要供别人调用的API/信息放置到一个堆内存中,让utils指向这个堆,后期基于utils就可以访问到堆中的API
高级单例设计模式 [基于闭包管理的单例设计模式]
- 单独的实例:基于单独的实例,来管理自己模块下的内容,保证不冲突 [实现的是分组]
- namespace: 命名空间
把描述相同的事物的属性和方法放置在同一个命名空间下,来实现分组的特点,减少全局变量污染 => 单例设计模式 而基于闭包的方式,可以实现模块下部分方法的私有化,也可以基于单例实现API之间的公用 -> 最早期的模块化编程思想
- AMD(require.js)
- CMD(sea.js)
- CommonJS(Node.js)
- ES6Module
- ...
let namespace1 = {}; //Object的一个实例
let namespace2 = {}; //Object的一个实例
let utils = (function () {
const debounce = function debounce() {},
const toType = function toType() {};
// ...
return {
// ES6 debounce:debounce
debounce,
toType
};
})();
// 搜索区域
let searchModule = (function () {
let value = null;
const submit = function submit() {};
const func = function func() {
// ...
}
utils.debounce(func);
return {
submit
}
})();
// 天气区域
let weatherModule = (function () {
let city = '北京';
const queryData = function queryData(callback) {
let data = null;
callback && callback(data);
}
const bindHTML = function bindHTML() {};
const changeCity = function changeCity() {};
return {
init() {
// init中管控当前模块下各个业务功能的执行顺序 [大脑] -> 命名设计模式
queryData(function () {
bindHTML();
changeCity();
});
}
};
})();
weatherModule.init();
惰性函数
/* function getCss(element, attr) {
// 处理兼容
if (window.getComputedStyle) {
return window.getComputedStyle(element)[attr];
}
return element.currentStyle[attr];
} */
/* let utils = (function () {
let compatible = window.getComputenStyle ? true : false;
let getCss = function getCss() {
if (compatible) {
return window.getComputedStyle(element)[attr];
}
return element.currentStyle[attr];
}
return {
getCss
}
})(); */
// 需求:一个超级复杂的业务函数,而且会被执行N次,后续执行,依然想使用第一次执行处理好的逻辑,这样我们不期望每一次执行,逻辑都重新判断一下,此时基于惰性思想[函数重构可以实现性能的优化]
function getCss() {
if (window.getComputedStyle) {
getCss = function (element, attr) {
return window.getComputedStyle(element)[attr];
}
} else {
getCss = function (element, attr) {
return element.currentStyle[attr];
}
}
// 第一次把重写后的函数执行,获取对应的样式
return getCss(element, attr);
}
let body = document.body;
console.log(getCss(body, 'width'));
console.log(getCss(body, 'height'));
柯里化函数
预先处理的思想[利用闭包,保存私有上下文中的一些信息,供其下级上下文中调取使用,也就是我们把一些信息先预先保存下来,后期让其下级上下文使用] => 大函数执行返回小函数
const fn = (...params) => {
// 闭包: params -> [1,2]
return (...args) => {
return params.concat(args).reduce((total, item) => {
return total + item;
});
}
}
fn(1,2)(3);