Append code to the end of an existing function

后端 未结 5 1982
别那么骄傲
别那么骄傲 2021-02-04 03:17

I need to trigger function bar() whenever function foo() fires. I have no control over function foo or whether it will change in the future. I have this situation regularly (and

5条回答
  •  一整个雨季
    2021-02-04 04:08

    You can append or prepend some new code to an existing function just merging them using for example:

    function mergeFunctions(function1, function2, instance1, instance2, numberOfArgumentsToPassToFunc1) {
        return function() {
            var _arguments  = Array.prototype.slice.apply(arguments);
            var _arguments1 = _arguments.slice(0, numberOfArgumentsToPassToFunc1);
            var _arguments2 = _arguments.slice(numberOfArgumentsToPassToFunc1);
            var that = this;
            (function(function1, function2) {
                if (typeof function1 == "function") {
                    if (typeof instance1 != "undefined") {
                        function1.apply(instance1, _arguments1);
                    }
                    else if (that == window) {
                        function1.apply(function1, _arguments1);
                    }
                    else {
                        var compare = mergeFunctions(function(){}, function(){});
                        if (that.toString() == compare.toString()) {
                            function1.apply(function1, _arguments1);
                        }
                        else {
                            function1.apply(that, _arguments1);
                        }
                    }
                }
                if (typeof function2 == "function") {
                    if (typeof instance2 != "undefined") {
                        function2.apply(instance2, _arguments2);
                    }
                    else if (that == window) {
                        function2.apply(function2, _arguments2);
                    }
                    else {
                        var compare = mergeFunctions(function(){}, function(){});
                        if (that.toString() == compare.toString()) {
                            function2.apply(function2, _arguments2);
                        }
                        else {
                            function2.apply(that, _arguments2);
                        }
                    }
                }
            })(function1, function2);
        }
    }
    



    A basic example would be the following:

    // Original function:
    var someFunction = function(){
        console.log("original content");
    };
    
    // Prepend new code:
    // --------------------------------------------------------
    someFunction = mergeFunctions(function() {
        console.log("--- prepended code");
    }, someFunction);
    
    // Testing:
    someFunction();
    
    // Outout:
    // [Log] --- prepended code
    // [Log] original content
    
    
    // Append new code:
    // --------------------------------------------------------
    someFunction = mergeFunctions(someFunction, function() {
        console.log("appended code");
    });
    
    // Testing:
    someFunction();
    
    // Output:
    // [Log] --- prepended code
    // [Log] original content
    // [Log] appended code
    



    Note that the merging function tries to apply the expected 'this' to the merged parts, otherwise you can just simply pass the wanted 'this' to them, as well as you can handle the relative arguments.
    A more general example could be the following:

    function firstPart(a, b) {
        console.log("--- first part");
        console.log("'this' here is:");
        console.log(this.name);
        console.log("a: "+a);
        console.log("b: "+b);
    }
    
    function MyObject() {
        this.x = "x property of MyObject";
    }
    
    MyObject.prototype.secondPart = function (y) {
        console.log("");
        console.log("--- second part");
        console.log("'this' here is:");
        console.log(this.name);
        this.x = y;
        console.log("x: "+this.x);
    }
    
    MyObject.prototype.merged = mergeFunctions(firstPart, MyObject.prototype.secondPart, firstPart, MyObject, 2);
    
    // Testing
    var test = new MyObject();
    test.merged("a parameter", "b parameter", "x parameter overrides x property of MyObject");
    
    // Console output:
    // [Log] --- first part
    // [Log] 'this' here is:
    // [Log] firstPart
    // [Log] a: a parameter
    // [Log] b: b parameter
    // [Log] 
    // [Log] --- second part
    // [Log] 'this' here is:
    // [Log] MyObject
    // [Log] x: x parameter overrides x property of MyObject
    

提交回复
热议问题