首先看一段代码
/* * 注册事件 * @param {HTMLElement} ele 元素 * @param {string} eventName 事件名 * @param {Function} handler 事件处理函数 */ function addEvent(ele, eventName, handler){ if(ele.addEventListener) { ele.addEventListener(eventName, handler); } else if(ele.attachEvent) { ele.addEventListener(eventName, handler); } else { ele['on' + eventName] = handler; } }
代码很简单就是一个元素注册事件的兼容性函数
分析:
每次调用该函数给元素注册事件,都会经过这一系列判断
其实这些没有必要,因为浏览器支持哪一种事件,在打开页面的时候就已经知道了
所以,事件注册方式,在一开始就能确定了,
我们可以注册一个IIFE立即执行函数,在一开始的时候就把注册事件方式给确定下来
var addEvent = (function(){ if(ele.addEventListener) { return function(ele, eventName, handler) { ele.addEventListener(eventName, handler); } } else if(ele.attachEvent) { return function(ele, eventName, handler) { ele.addEventListener(eventName, handler); } } else { return function(ele, eventName, handler) { ele['on' + eventName] = handler; } } }) ()
使用场景1:
// request请求 兼容window 与node环境 function request(options) { if(typeof window != 'undefined') { // 浏览器ajax } else { // node的http } }
优化后
const request = (() => { if(typeof window != 'undefined') { return (options) => { // 浏览器ajax } } else { return (options) => { // node的http } } })()
使用场景2:
function removeSpace(str) { return str.replace(/\s/g, ''); } // 工具函数,去除字符串的空白,但是每次调用, // 都会建立一个正则(或者甚至占用内存大的东西),使用多了后,就会导致内存忽上忽下
// 注册变量,但是有个问题,该变量受到闭包影响,会永远存在,不会主动释放 const removeSpace = (() => { const reg = /\s/g, replacement = ''; return (str) => str.replace(reg, replacement); })()
// 主动释放内存 const createRemoveSpace = () => { const reg = /\s/g, replacement = ''; return (str) => str.replace(reg, replacement); }) // 使用 let createSpace = createRemoveSpace(); createSpace('ad a asdasdasdasd asdas s'); createSpace('ad a asdasdasdasd asdas s'); createSpace('ad a asdasdasdasd asdas s'); createSpace('ad a asdasdasdasd asdas s'); // 使用结束后,主动销毁并释放内存 createSpace = null;