Can you alter a Javascript function after declaring it?

前端 未结 12 774
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-28 22:10

Let\'s say I have var a = function() { return 1; }. Is it possible to alter a so that a() returns 2? Perhaps by editing a

相关标签:
12条回答
  • 2020-11-28 22:32

    I used something like this to modify an existing function whose declaration was not accessible to me:

    // declare function foo
    var foo = function (a) { alert(a); };
    
    // modify function foo
    foo = new Function (
      "a",
      foo.toSource()
        .replace("alert(a)", "alert('function modified - ' + a)")
        .replace(/^function[^{]+{/i,"")  // remove everything up to and including the first curly bracket
        .replace(/}[^}]*$/i, "")  // remove last curly bracket and everything after<br>
    );
    

    Instead of toSource() you could probably use toString() to get a string containing the function's declaration. Some calls to replace() to prepare the string for use with the Function Constructor and to modify the function's source.

    0 讨论(0)
  • 2020-11-28 22:32
    var a = function() { return 1; }
    alert(a()) // 1
    a = function() { return 2; }
    alert(a()) // 2
    

    technically, you're losing one function definition and replacing it with another.

    0 讨论(0)
  • 2020-11-28 22:34

    You can change functions like other objects

    var a1 = function(){return 1;}
    var b1 = a1;
    a1 = function(){
      return b1() + 1;
    };
    console.log(a1()); // return 2
    
    // OR:
    function a2(){return 1;}
    var b2 = a2;
    a2 = function(){
      return b2() + 1;
    };
    console.log(a2()); // return 2

    0 讨论(0)
  • 2020-11-28 22:35

    Can you not just define it again later on? When you want the change try just redefining it as:

    a = function() { return 2; }
    
    0 讨论(0)
  • 2020-11-28 22:36

    All feasible solutions stick to a "function wrapping approach". The most reliable amongst them seems to be the one of rplantiko.

    Such function wrapping easily can be abstracted away. The concept / pattern itself might be called "Method Modification". Its implementation definitely belongs to Function.prototype. It would be nice to be backed one day by standard prototypal method modifiers like before, after, around, afterThrowing and afterFinally.

    As for the aforementioned example by rplantiko ...

    function a () { return 1; }
    
    // redefine
    a = (function () {
      var _a = a;
      return function () {
        // You may reuse the original function ...
        // Typical case: Conditionally use old/new behaviour
        var originalResult = _a.apply(this, arguments);
        // ... and modify the logic in any way
        return originalResult + 1;
      };
    })();
    
    a(); // --> gives 2
    

    ... and making use of [around], the code would transform to ...

    function a () { return 1; }
    
    console.log("a : ", a);
    console.log("a() : ", a());
    
    
    a = a.around(function (proceed, interceptor, args) {
      return (proceed() + 1);
    });
    
    console.log("a : ", a);
    console.log("a() : ", a());
    
    0 讨论(0)
  • 2020-11-28 22:39

    I am sticking to jvenema's solution, in which I don't like the global variable "old". It seems better to keep the old function inside of the new one:

    function a() { return 1; }
    
    // redefine
    a = (function(){
      var _a = a;
      return function() {
      // You may reuse the original function ...
      // Typical case: Conditionally use old/new behaviour
        var originalResult = _a.apply(this, arguments);
      // ... and modify the logic in any way
        return originalResult + 1;
        }
    })();
    a()  // --> gives 2
    
    0 讨论(0)
提交回复
热议问题