Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

overriding a global function in javascript

I am trying to add my own error handling to the JavaScript setTimeout function. The following code works fine in 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);
}

But in IE7 it turns into a recursive function. For some reason oldSetTimeout gets set to the new function.

Any suggestions?



side note: Yes, I need to do it this way. I am using a pile of 3rd party libraries all of which don't deal with setTimeout well, so I can't just change the calls to setTimeout.
like image 937
alumb Avatar asked Sep 28 '10 17:09

alumb


People also ask

Can you override function in JavaScript?

Introduction. It is true that JavaScript supports overriding, not overloading. When you define multiple functions that have the same name, the last one defined will override all the previously defined ones and every time when you invoke a function, the last defined one will get executed.

What is global function in JavaScript?

The global object in JavaScript is an always defined object that provides variables and functions, and is available anywhere. In a web browser, the global object is the window object, while it is named global in Node. js. The global object can be accessed using the this operator in the global scope.


2 Answers

This is because you're using named function expressions, which are incorrectly implemented in IE. Removing the function names will fix the immediate problem. See kangax's excellent article on this subject. However, there's another problem that isn't so easily fixed.

In general, it's not a good idea to attempt to override properties of host objects (such as window, document or any DOM element), because there's no guarantee the environment will allow it. Host objects are not bound by the same rules as native objects and in essence can do what they like. There's also no guarantee that a host method will be a Function object, and hence oldSetTimeout may not have always have an apply() method. This is the case in IE, so the call to oldSetTimeout.apply(this, args); will not work.

I'd suggest the following instead:

window.oldSetTimeout = window.setTimeout;

window.setTimeout = function(func, delay) {
    return window.oldSetTimeout(function() {
        try {
            func();
        }
        catch (exception) {
            //Do Error Handling
        }
    }, delay);
};
like image 170
Tim Down Avatar answered Nov 04 '22 09:11

Tim Down


Minor improvement to the Answer of Tim Down to mimic the original even more:

window.oldSetTimeout = window.setTimeout;
window.setTimeout = function(func, delay) {
    return window.oldSetTimeout(function() {
        try {
            func();
        }
        catch (exception) {
            //Do Error Handling
        }
    }, delay);
};
like image 39
Tim Avatar answered Nov 04 '22 08:11

Tim