以下JS高阶编程技巧均属于闭包的高级应用。
文章有点长,请耐心食用
惰性函数思想
我们来举个例子证明JS中的惰性函数思想。
以单击响应事件为例,
- DOM 0 级事件绑定方式为:
元素.onclick = function(){…}
- DOM 2 级事件绑定方式(大多数)为:
元素.addEventListener("click",function(){…})
,但这种方式不被IE6~8所支持,在低版本浏览器中采用这种方式:元素.attachEvent("onclick",function(){…})
我们希望基于DOM2进行事件绑定,并兼容所有浏览器。
自然而然需要进行判断:
/* observerEvent:基于DOM2进行事件绑定
* @params:
* element: 需要绑定事件的元素
* type: 绑定的事件类型
* func: 事件响应函数
* @return: undefined
*/
function observerEvent(element,type,func){
if(element.addEventListener){
element.addEventListener(type, func); // 如果有这个就用这个
}else if(element.attachEvent){
element.attachEvent("on" + type, func); // 不行的话有这个用它也可以
}else{
element["on" + type] = func; // 再不行就得用DOM0事件绑定方法
}
}
这个方法可以实现功能,但如果多次执行,每一次都要判断浏览器的兼容性,是在有点麻烦。我们希望在第一次执行方法的时候做一次判断,以后不要重复判断了。
function observerEvent(element,type,func){
if(element.addEventListener){
observerEvent = function(element,type,func){
element.addEventListener(type, func);
}
}else if(element.attachEvent){
observerEvent = function(element,type,func){
element.attachEvent("on" + type, func);
}
}else{
observerEvent = function(element,type,func){
element["on" + type] = func;
}
}
observerEvent(element,type,func);
}
以上代码主要做了两点修改:
- 函数第一次执行,无论进入哪一个判断,大函数形成的私有上下文都会产生一个新的函数堆,并且将这个堆的地址赋给全局的observerEvent变量