利用立即执行函数IIFE提升性能

339 阅读3分钟

示例一

为某个元素注册一个事件,提供事件的处理函数

存在的问题

function addEvent(ele, eventName, handler) {
	if (ele.addEventListener) {
		ele.addEventListener(eventName, handler);
	} else if (ele.attachEvent) {
		ele.attachEvent('on'+eventName, handler);
	} else {
		ele['on'+eventName] = handler;
	}
}
  • 函数内部处理了浏览器的兼容性问题
  • 每次调用该方法注册事件的时候,都需要经过一系列的判断,实际上是没有必要的
  • 用户的浏览器环境是确定的,到底支持哪一种事件注册方式在最开始的时候就可以确定下来

优化

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.attachEvent('on'+eventName, handler);
		}
	} else {
		return function (ele, eventName, handler) {
			ele['on'+eventName] = handler;
		}
	}
})()
  • 使用立即执行函数,把判断放到立即执行函数里面,这些判断在最开始的时候就会运行,而不用等到调用该函数的时候才执行
  • 在每个分支里面,为每个环境返回特定的事件注册函数,将来用户使用的时候直接就使用特定环境的时间注册函数

示例二

发送请求,适配浏览器环境和node环境


function request (options) {
 	if (typeof window !== 'undefined') {
 		// 浏览器环境的ajax
 	} else {
 	     // node环境
 	}
}
  • 到底是浏览器环境还是node环境在最开始就能确认,不用等到调用的时候才去进行判断

var request = (function(){
	if (typeof window !== 'undefined') {
 		// 浏览器环境的ajax
 		return (options) => {}
 	} else {
 	     // node环境
 	     return (options) => {}
 	}

})()

示例三

存在的问题

function removeSpace (str) {
      	var regexep = /\s/g;
	return str.replace(regexep, '');
}
  • 正则是一个对象肯定会占用内存空间
  • 不起眼的空字符串仍然会占用内存空间
  • 每次调用该函数都会重新生成正则对象,和一个空字符串,都会占用内存,
  • 如果调用该函数的次数变多了,会发现内存占用的曲线图是波动很大, 忽上忽下;函数的执行期间就会上升,函数结束完成后到达某个垃圾回收的时间点,它内存就会下降,因为内存会被回收;下次调用的时候会升高又会下降
  • 不能保证函数内部占用的内存很少,如果占用的很多就会出现问题
  • 内存忽上忽下带来的开销是很大的

优化

立即执行函数

var removeSpace = (function() {
	  var regexep = /\s/g;
	 return (str) => str.replace(regexep, '');
})()
  • 正则对象只会占用一份内存空间,下次调用不会重新分配内存空间;内存不会忽上忽下
  • 想释放内存的时候,不能removeSpace = null,否则该函数就不能使用了
  • 但是问题是:正则对象受到了闭包的影响,它会全局的长久的停留到内存空间里面

高阶函数

var createRemoveSpace = function() {
	 var regexep = /\s/g;
	 return (str) => str.replace(regexep, '');
}

var removeSpace  = createRemoveSpace();
removeSpace('abc');
removeSpace('def');
removeSpace('ghx');
removeSpace = null;
  • 把立即执行函数改成高阶函数
  • 不是立即执行函数说有在没有执行之前不会占用内存空间
  • 在第一次调用的时候才会生成占用内存的正则对象
  • 第二次调用正则对象只会占用一份内存空间,内存占用会比较平稳,不会忽上忽下
  • 当不再使用removeSpace函数时候就把其设置为null,该函数就会被垃圾回收,然后高阶函数依赖的正则对象也就会垃圾回收期回收,不会永久驻留到内存中