2010-09-28 14 views
7

Próbuję dodać własną obsługę błędów do funkcji JavaScript setTimeout. Poniższy kod działa poprawnie w chrome:nadpisywanie funkcji globalnej w 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); 
} 

Ale w IE7 zmienia się w funkcję rekursywną. Z jakiegoś powodu oldSetTimeout zostaje ustawiona na nową funkcję.

Wszelkie sugestie?



dygresja: Tak, muszę zrobić to w ten sposób. Używam stosu bibliotek innych firm, z których wszystkie nie radzą sobie dobrze z setTimeout, więc nie mogę po prostu zmienić wywołań na setTimeout.

Odpowiedz

16

Dzieje się tak, ponieważ używasz nazwanych wyrażeń funkcji, które są niepoprawnie zaimplementowane w IE. Usunięcie nazw funkcji naprawi natychmiastowy problem. Zobacz kangax 's excellent article on this subject. Istnieje jednak inny problem, który nie jest tak łatwo naprawiony.

Ogólnie rzecz biorąc, nie jest dobrym pomysłem próba zastąpienia właściwości obiektów hosta (takich jak window, document lub dowolny element DOM), ponieważ nie ma gwarancji, że środowisko na to pozwoli. Obiekty hosta nie są związane tymi samymi regułami, co obiekty natywne iw zasadzie mogą robić, co im się podoba. Nie ma również gwarancji, że metoda hosta będzie obiektem Function, a zatem oldSetTimeout może nie zawsze mieć metodę apply(). Tak jest w IE, więc połączenie z oldSetTimeout.apply(this, args); nie zadziała.

sugeruję następujące zamiast:

window.oldSetTimeout = window.setTimeout; 

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

Minor ulepszeniem Odpowiedź Tim dół, aby naśladować oryginalny nawet więcej:

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

dobry punkt. Dokonałem zmiany w mojej odpowiedzi; Mam nadzieję, że nie masz nic przeciwko. –

+3

lol, ale teraz jest do odpowiedzi mówiąc to samo>: | –

Powiązane problemy