2010-09-28 28 views
7

Estoy tratando de agregar mi propio manejo de errores a la función de JavaScript setTimeout. El siguiente código funciona bien en cromo:anulando una función global en javascript

var oldSetTimeout = window.setTimeout; 
window.setTimeout = function setTimeout(func, delay) { 
    var args = Array.prototype.slice.call(arguments, 0); 
    args[0] = function timeoutFunction() { 
     var timeoutArgs = Array.prototype.slice.call(arguments, 0); 
     try { 
      func.apply(this,timeoutArgs); 
     } 
     catch (exception) { 
      //Do Error Handling 
     } 
    } 
    return oldSetTimeout.apply(this, args); 
} 

Pero en IE7 se convierte en una función recursiva. Por alguna razón, oldSetTimeout se establece en la nueva función.

¿Alguna sugerencia?



nota al margen: Sí, tengo que hacerlo de esta manera. Estoy usando una pila de librerías de terceros, todas las cuales no manejan bien el setTimeout, así que no puedo simplemente cambiar las llamadas a setTimeout.

Respuesta

16

Esto se debe a que está usando las expresiones de función nombradas, que se implementan incorrectamente en IE. La eliminación de los nombres de las funciones solucionará el problema inmediato. Ver kangax 's excellent article on this subject. Sin embargo, hay otro problema que no se soluciona tan fácilmente.

En general, no es una buena idea intentar anular las propiedades de objetos host (como window, document o cualquier elemento DOM), porque no hay garantía de que el entorno lo permita. Los objetos host no están sujetos a las mismas reglas que los objetos nativos y, en esencia, pueden hacer lo que quieran. Tampoco hay garantía de que un método host sea un objeto Function, y por lo tanto oldSetTimeout puede no tener siempre un método apply(). Este es el caso en IE, por lo que la llamada a oldSetTimeout.apply(this, args); no funcionará.

me gustaría sugerir lo siguiente en su lugar:

window.oldSetTimeout = window.setTimeout; 

window.setTimeout = function(func, delay) { 
    return window.oldSetTimeout(function() { 
     try { 
      func(); 
     } 
     catch (exception) { 
      //Do Error Handling 
     } 
    }, delay); 
}; 
3

mejoras menores en la respuesta de Tim hacia abajo para imitar el original aún más:

window.oldSetTimeout = window.setTimeout; 
window.setTimeout = function(func, delay) { 
    return window.oldSetTimeout(function() { 
     try { 
      func(); 
     } 
     catch (exception) { 
      //Do Error Handling 
     } 
    }, delay); 
}; 
+0

Buen punto. Hice el cambio a mi respuesta; Espero que no te moleste. –

+3

lol, pero ahora hay respuestas que dicen lo mismo>: | –

Cuestiones relacionadas