在不使用bind将'this'和参数传递给addEventListener函数的讨论中,提到了缓存函数。
例如,考虑以下事件侦听器:
window.addEventListener('event1', callback1, false);
window.addEventListener('event2', callback2, false);
window.addEventListener('event3', callback3, false);
window.addEventListener('event4', callback4, false);
window.addEventListener('event5', callback5, false);
它们的删除是否可以缓存(例如在数组中)?
var unloaders = []; // Keeps track of unloader functions
unloaders.push(window.removeEventListener('event1', callback1, false));
unloaders.push(window.removeEventListener('event2', callback2, false));
unloaders.push(window.removeEventListener('event3', callback3, false));
unloaders.push(window.removeEventListener('event4', callback4, false));
unloaders.push(window.removeEventListener('event5', callback5, false));
最后,如果它们可以被缓存,它们如何在正确的时间执行?
for (let i = 0, len = unloaders.length; i < len; i++) {
//
}
unloaders.push(window.removeEventListener('event1', callback1, false))
不会将函数放入稍后执行的数组中,而是执行函数并将结果值放入数组中,即不是您想要的。
另一个问题中的unload
实际上将构造一个匿名闭包函数并将其放入数组中,因此简化为:
var unloaders = []; // Keeps track of unloader functions
unloaders.push(function() {
window.removeEventListener('event2', callback2, false);
});
这有点类似于绑定函数并将绑定的函数放入数组,因此以下操作将产生相同的结果:
// This just binds the function, effectively creating a new function,
// but does not execute it (yet)
var bound = window.removeEventListener.bind(window, 'event2', callback2, false);
unloaders.push(bound);
我更喜欢第一种风格,但两者都是可以的,实际上没有闭包,但绑定函数可能会避免一些问题,在某些情况下,闭包关闭了太多的东西,使其人为地保持活力。但这通常是罕见的。
无论如何,最后调用存储在数组中的函数,你只需要迭代它,然后一个接一个地调用函数。
for (let i = 0, len = unloaders.length; i < len; i++) {
unloaders[i]();
}
但是,为了避免异常提前退出循环,我建议您将调用包装在try-catch中。
for (let i = 0, len = unloaders.length; i < len; i++) {
try {
unloaders[i]();
}
catch (ex) {
// Do something
}
}
实际上,以相反的顺序(后进先出)调用卸载器可能更可取。
for (let i = unloaders.length - 1; i >= 0; i--) {
try {
unloaders[i]();
}
catch (ex) {
// Do something
}
}
来自另一个问题的unload
函数有一些更多的魔法在它:它返回一个函数,允许您调用卸载程序,您刚刚注册在任何时候,正确地从unloaders
数组中删除它。这对于我提供的unloadWindow
函数很重要。