2010-09-28 5 views
7

Sto cercando di aggiungere la mia gestione degli errori alla funzione setTimeout di JavaScript. Il seguente codice funziona bene in chrome:sovrascrivere una funzione globale in 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); 
} 

Ma in IE7 si trasforma in una funzione ricorsiva. Per qualche motivo, oldSetTimeout viene impostato sulla nuova funzione.

Qualche suggerimento?



lato nota: Sì, ho bisogno di farlo in questo modo. Sto usando una pila di librerie di terze parti che non si occupano bene di setTimeout, quindi non posso semplicemente cambiare le chiamate a setTimeout.

risposta

16

Questo perché si utilizzano le espressioni di funzione denominate, che sono state implementate in modo errato in IE. La rimozione dei nomi delle funzioni risolverà il problema immediato. Vedi kangax's excellent article on this subject. Tuttavia, c'è un altro problema che non è così facilmente risolto.

In generale, non è una buona idea per tentare di escludere proprietà degli oggetti host (come window, document o qualsiasi elemento DOM), perché non c'è garanzia dell'ambiente lo permette. Gli oggetti host non sono vincolati dalle stesse regole degli oggetti nativi e in sostanza possono fare ciò che vogliono. Non è inoltre garantito che un metodo host sia un oggetto Function e, pertanto, oldSetTimeout potrebbe non avere sempre un metodo apply(). Questo è il caso in IE, quindi la chiamata a oldSetTimeout.apply(this, args); non funzionerà.

Io suggerirei il seguente invece:

window.oldSetTimeout = window.setTimeout; 

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

miglioramento Minore alla risposta di Tim giù per imitare l'ancor più originale:

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

Buon punto. Ho apportato la modifica alla mia risposta; Spero non ti dispiaccia. –

+3

lol, ma ora c'è una risposta che dice lo stesso>: | –