2010-09-28 58 views
7

我想将自己的错误处理添加到JavaScript setTimeout函数中。下面的代码可以在Chrome中正常工作:在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); 
} 

但是在IE7中,它变成了一个递归函数。由于某种原因,oldSetTimeout被设置为新功能。

有什么建议吗?



侧面说明:是的,我需要做的是这样的。我正在使用一堆第三方库,所有这些库都不能很好地处理setTimeout,所以我不能只是将调用更改为setTimeout。

回答

16

这是因为您使用命名的函数表达式,它们在IE中不正确实现。删除函数名称将解决当前的问题。请参阅kangaxexcellent article on this subject。但是,还有一个问题不容易解决。

通常,尝试覆盖主机对象的属性(例如windowdocument或任何DOM元素)并不是一个好主意,因为不能保证环境允许它。主机对象不受本地对象相同的规则约束,本质上可以做他们喜欢的事情。也不能保证主机方法将是一个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); 
}; 
3

未愈添下的应答模仿甚至原来多:

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

好一点。我改变了我的答案;我希望你不介意。 – 2013-12-11 12:21:18

+3

大声笑,但现在有答案说相同>:| – 2015-02-15 08:25:45