惰性函数
应用一: 事件绑定的兼容性处理
DOM 0 事件绑定: xxx.onclick=function() {}
DOM 2 事件绑定: xxx.addEventListener('click', function() {}) , 只不过不兼容 IE6~8,地版本浏览器是基于 xxx.attachEvent('onclick', function() {}) 实现的
// 这种写法虽然可以实现需求和效果,但是在相同页面中,每一次执行函数,进来后都要重复进行兼容判断
// 但是理论上第一次执行,就已经知道兼容性了,后期再执行,没必要每一次都判断兼容,也就是把兼容之处理一次
/* function observeEvent(element, type, func) {
if(element.addEventListener) {
element.addEventListener(type, func);
} else if (element.attachEvent) {
element.attachEvent('on' + type, func);
} else {
element['on' + type] = func;
}
} */
// => 优化: 根据兼容判断,重构函数并执行,后期的调用都不再进行兼容判断
function observeEvent(element, type, func) {
// 第一次执行 observeEvent,根据兼容判断,重构了这个函数,重构后的小函数是不需要做兼容处理的
if(element.addEventListener) {
observeEvent = function(element, type, func) {
element.addEventListener(type, func);
}
} else if (element.attachEvent) {
observeEvent = function(element, type, func) {
element.attachEvent('on' + type, func);
}
} else {
observeEvent = function(element, type, func) {
element['on' + type] = func;
}
}
// 第一次也需要执行重构后的方法,实现事件绑定
observeEvent(element, type, func);
}
// observeEvent(xxx,'click',function() {});
应用二: 单例设计模式
JS 中另一个业务逻辑开发中常用到的基础设计思想"单例设计模式",也是基于惰性思想(框架开发模式下无需使用单例处理)最早的模块开发思想 (AMD/CMD/CommonJS/ES6Module)
//=> A开发天气模块
//=> wetherModule 除了是全局变量,模块名称,对象名,更专业的叫法是命名空间(给堆起了一个变量名,代表这个堆),这样单例设计模式就是把魔术相同事务(相同板块)中的属性和方法归总到相同的命名空间下,实现分组管理(既可以避免全局变量污染,也可以实现模块之间的相互调用)
let wetherModule = (function () {
//=> 也叫命名空间
let index = 0;
function queryData() {}
function getElement() {}
// 想让闭包之外的东西调用方法
//=>方法一: 基于 window.xxx 暴露到全局上(如果向全局暴露的东西过多,也会存在冲突的问题)
// window.getElement = getElement;
//=>方法二: 建议使用 return 的方式
return {
getElement
};
})();
//=> B开发资讯模块
let informationModule = (function () {
let index = 0;
function queryData() {}
// 调用 wetherModule 模块的 getElement
wetherModule.getElement();
function bindHTML() {}
function handleEvent() {}
return {
//=> init: function() {}
init() {
// 在单例设计模式的基础上,增加一个命令模式:
// init作为当前模块业务入口,以后只需要执行 informationModule.init(),我们在 init 中根据业务需求,把编写的方法按照顺序依次调用执行即可
queryData();
bindHTML();
handleEvent();
}
};
})();