Wrapping an old function with a new piece of functionality

from jquery ninja book

by dandoyon

JavaScript

Function.prototype.bind = function() {
    var fn = this,
        args = Array.prototype.slice.call(arguments),
        object = args.shift();
    return function() {
        return fn.apply(object, args.concat(Array.prototype.slice.call(arguments)));
    };
};

function wrap(object, method, wrapper) {
    var fn = object[method];
    return object[method] = function() {
        return wrapper.apply(this, [fn.bind(this)].concat(
        Array.prototype.slice.call(arguments)));
    };
};

// Example adapted from Prototype
if (Prototype.Browser.Opera) {
    wrap(Element.Methods, "readAttribute", function(orig, elem, attr) {
        return attr == "title" ? elem.title : orig(elem, attr);
    });
}

/*

The wrap() function overrides an existing method (in this case readAttribute)
replacing it with a new function. However, this new function still has access to the original
functionality (in the form of the original argument) provided by the method. This means
that a function can be safely overridden without any loss of functionality.

*/