Search code examples
javascriptmonkeypatching

Overriding a javascript function definition


I am trying to monkeypatch a 3rd party javascript library but the original function definition I am overloading keeps getting called.

var ns = {};

ns.topFxn = function(){
    var _me = "me";
    function _toOverride(){
        console.log("This is the original: " + _me);
    }
    function pubFxn(){
        _toOverride();
    }
    console.log("Original");
    ns.pubFxn = pubFxn;
};

//attempt to monkey patch
var oldTopFxn = ns.topFxn;
ns.topFxn = function(){
    oldTopFxn();
    function _toOverride(){
        console.log("This is the overriden: " + _me);
    }
    console.log("MonkeyPatch");
};

ns.topFxn();
ns.pubFxn();

OUTPUT:

scratch.js:15> Original
scratch.js:26> MonkeyPatch
scratch.js:10> This is the original: me

I think this is because this function is indirectly called by another function, and that function might hold a closure on the function it is pointing to - so maybe this isn't possible? Any suggestions on how to override?

jsfiddle


Solution

  • You can't override a local function in another function, because of variable scope. The name _toOverride is local to each function, and assigning it in your function has no effect on the function with the same name in a different function.

    You would have to override ns.pubFxn.

    var oldTopFxn = ns.topFxn;
    ns.topFxn = function(){
        oldTopFxn();
        var oldPubFxn = ns.pubFxn;
        function _toOverride(){
            console.log("This is the overriden: " + _me);
        }
        ns.pubFxn = function() {
            oldPubFxn();
            _toOverride();
        }
        console.log("MonkeyPatch");
    };