覆盖javascript中的全局函数

时间:2010-09-28 17:12:31

标签: javascript override global settimeout

我正在尝试将自己的错误处理添加到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 个答案:

答案 0 :(得分:17)

这是因为你正在使用命名函数表达式,它们在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);
};

答案 1 :(得分:3)

对Tim Down的回答进行了一些改进,以更加模仿原作:

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