- 外观模式
由于子系统或者程序组成比较复杂而提供一个高层面的接口,该模式对外有一个统一的接口,可以在使用的时候不用知道内部的详细逻辑,降低原有系统的使用复杂度。较多用在处理兼容不同平台的问题。
外观模式的一个经典实现:addEvent函数
function addEvent(dom, type, fn) {
if (dom.addEventListener) { dom addEventListener(type, fn, false) }else if (dom.attactEvent) { dom.attachEvent('on' + type, fn) }else { dom['on' + type] } }
const myInput = document.getElementById('myInput')
addEvent(myInput, 'click', function() {
console.log('绑定事件')
})
onclick和click绑定事件的区别:
onclick可以被覆盖,当需要同时执行多个事件时,需要使用addEventListener, addEventListener可以在同一dom上绑定多个事件,并且不会覆盖,在触发click事件时,绑定事件按顺序执行。
导出文件,用于兼容不同浏览器,调用时只需要调用暴露出来的最外层接口即可。
export function exportDownload(exportData, suffix, fileName) {
const blob = new Blob([exportData])
if ('download' in document.createElement('a')) {
const elink = document.createElement('a')
elink.style.display = 'none'
elink.download = fileName + suffix
elink.href = URL.createObjectURL(blob)
document.body.appendChild(elink)
elink.click()
URL.revokeObjectURL(elink.href)
document.body.removeChild(elink)
} else {
navigatoe.msSaveBlob(blob, new Date().getTime() + suffix)
}
}
一键遥控
class Light { on() { console.log('打开灯') } off() { console.log('关掉灯') } } class Computer { on() { console.log('打开电脑') } off() { console.log('关掉电脑') } } class Aircondition { on() { console.log('打开空调') } off() { console.log('关掉空调') } } let light = new Light(), computer = new Computer(), aircondition = new Aircondition() class Facade { on() { light.on() computer.on() aircondition.on() } off() { light.off() computer.off() aircondition.off() } } let facade = new Facade() facade.on() // 打开灯 // 打开电脑 // 打开空调 facade.off() // 关掉灯 // 关掉电脑 // 关掉空调
- 惰性模式
减少每次代码执行时重复执行的某些分支判断,通过对对象的重定义来屏蔽原对象中的分支判断,提高网站性能。
针对上文中的不同浏览器的事件注册方法,每次绑定事件时,都需要进行检测判断, 但是在同一浏览器中每次检测判断的结果都时一样的,不可能走不同的分支。
惰性模式有两种实现方式:
加载即执行:在文件加载时就对方法进行重新定义,这样在之后的事件注册时就不需要再进行检测判断了,缺点:在页面加载的时候会消耗一定的资源。
var addEvent = function (dom, type, fn) { if (document.addEventListener) { return function (dom, type, fn) { dom.addEventListener(type, fn, false) } } else if (document.attachEvent) { return function (dom, type, fn) { dom.attachEvent('on' + type, fn) } } else { return function (dom, type, fn) { dom['on' + type] = fn } } }() console.log(addEvent) // f (dom, type, fn) { // dom.addEventListener(type, fn, false) // }
在页面加载完后打印addEvent方法,就发现addEvent方法已经和最初定义的不同了,说明addEvent方法在页面加载的过程中就已经被重新定义了。
惰性执行:在文件加载的时候不执行,第一次执行函数的时候才在函数内部对函数进行重写,最后再调用重写的方法将方法进行重新定义,优点:加载页面的时候不会执行,不消耗资源。缺点:第一次调用的时候会消耗一定的资源。
var addEvent = function (dom, type, fn) { if (dom.addEventListener) { addEvent = function (dom, type, fn) { dom.addEventListener(type, fn, false) } } else if (dom.attachEvent) { addEvent = function (dom, type, fn) { dom.attachEvent('on' + type, fn) } } else { addEvent = function (dom, type, fn) { dom['on' + type] = fn } } addEvent(dom, type, fn) } let dom1 = document.getElementById('btn') setTimeout(() => { addEvent(dom1, 'click', function () { console.log('按钮绑定事件') }) console.log(addEvent) // f(dom, type, fn) { // dom,addEventListener(type, fn, false) // } }, 1000) console.log(addEvent) // f(dom, type, fn) { // if (dom, addEventListener) { // addEvent = function (dom, type, fn) { // dom.addEventListener(type, fn, false) // } // } else if (dom.attachEvent) { // ad...
在页面加载后立即打印addEvent方法,输出结果和最初的定义一样,说明在页面加载的过程中并没有对addEvent进行重新定义,延迟1秒后调用addEvent给按钮绑定一个事件,绑定完后打印addEvent发现addEvent已经发生了改变,说明在第一次调用addEvent的时候它被重新定义了。