命令模式

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作


惰性加载函数

场景

写一个各浏览器兼容事件绑定函数

1
2
3
4
5
6
7
8
let addEvent = function (elem, type, handler) {
if (window.addEventListener) {
return elem.addEventListener(type, handler, false);
}
if (window.attachEvent) {
return elem.attachEvent('on' + type, handler);
}
}

缺点:每一次调用都必须执行一次if判断

方案一

在该代码被加载时,利用立即执行函数做一次判断,然后返回给addEvent正确的事件绑定函数

1
2
3
4
5
6
7
8
9
10
11
12
let addEvent = (function (){
if (window.addEventListener) {
return function (elem, type, handler) {
elem.addEventListener(type, handler, false);
}
}
if (window.attachEvent) {
return function (elem, type, handler) {
elem.attachEvent('on' + type, handler);
}
}
})()

缺点:如果addEvent绑定事件函数一直都没有被调用,那么就白白做了一次浏览器嗅探

方案二:惰性载入函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let addEvent = function(elem, type, handler) {
if (window.addEventListener) {
addEvent = function (elem, type, handler) {
elem.addEventListener(type, handler, false);
}
}
if (window.attachEvent) {
addEvent = function (elem, type, handler) {
elem.attachEvent('on' + type, handler);
}
}

addEvent(elem, type, handler);
}

缺点:首次调用较慢

参考

《Javascript设计模式与开发实践》


减少使用setInterval

setInterval很少使用在生成环境下,因为有如下几个缺点

缺点一:setInterval无视代码错误

setInterval执行的代码即使代码报错,它还会持续不断(不管不顾)地调用该代码

缺点二:setInterval无视网络延迟

假设你每隔一段时间就通过Ajax轮询一次服务器,看看有没有新数据(注意:如果你真的这么做了,那恐怕你做错了;建议使用“补偿性轮询”(backoff polling))。而由于某些原因(服务器过载、临时断网、流量剧增、用户带宽受限,等等),你的请求要花的时间远比你想象的要长。但setInterval不在乎。它仍然会按定时持续不断地触发请求,最终你的客户端网络队列会塞满Ajax调用。


CJS、ESM、UMD模块化标准

1. CommonJS

node.js的实现中采用了CommonJS标准的一部分,并在其基础上进行了一些调整

使用方式

使用requireexports或者module.exports进行模块的导入导出

1
2
3
4
5
6
7
8
9
10
// node.js为了简化操作,有var exports = module.exports
// 两者一致,那就说明,我可以使用任意一方来导出内部成员
console.log(exports === module.exports) // true

// 导出的对象近似于此种形式,exports相当于module.exports的引用
// var module = {
// exports: {
// foo: 'bar',
// }
// }