переопределение глобальной функции в javascript
Я пытаюсь добавить свою собственную обработку ошибок в функцию JavaScript setTimeout. Следующий код отлично работает в chrome:
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);
}
но в IE7 он превращается в рекурсивную функцию. Почему-то oldSetTimeout
получает значение новой функции.
какие предложения?
Примечание: Да, мне нужно сделать это таким образом. Я использую кучу сторонних библиотек, все из которых не имеют дело с setTimeout хорошо, поэтому я нельзя просто изменить вызовы на setTimeout.
2 ответов
это потому, что вы используете именованные функциональные выражения, которые неправильно реализованы в IE. Удаление имен функций устранит непосредственную проблему. См.kangax ' s отличная статья на эту тему. Однако, есть еще одна проблема, которую не так легко исправить.
в общем, не рекомендуется пытаться переопределить свойства объектов хоста (например,window
, document
или любой элемент DOM), потому что нет гарантия окружающей среды позволит это. Объекты хоста не связаны теми же правилами, что и собственные объекты, и по сути могут делать то, что им нравится. Также нет гарантии, что метод host будет Function
"объект", и, следовательно,oldSetTimeout
возможно, не всегда есть apply()
метод. Это имеет место в IE, поэтому вызов oldSetTimeout.apply(this, args);
не будет работать.
Я предлагаю следующее:
window.oldSetTimeout = window.setTimeout;
window.setTimeout = function(func, delay) {
return window.oldSetTimeout(function() {
try {
func();
}
catch (exception) {
//Do Error Handling
}
}, delay);
};
незначительное улучшение ответа Тима, чтобы еще больше имитировать оригинал:
window.oldSetTimeout = window.setTimeout;
window.setTimeout = function(func, delay) {
return window.oldSetTimeout(function() {
try {
func();
}
catch (exception) {
//Do Error Handling
}
}, delay);
};