如何动态更改函数

3

我有一个已经被赋值的函数,我想添加一些额外的脚本。当我像这样显示函数:

var func = obj.when_clicked;
alert(func);

以下内容将被显示:
function object_123(){
    object_123_Action();
}

类型是“函数”,该函数在我无法更改的其他地方执行,代码如下:

this.when_clicked();

我需要修改这个函数,加入自己的代码,使其变成:

function object_123(){
   object_123_Action();
   my_clicked(obj);
}

然后将其添加回来并覆盖when_clicked函数。

如果我手动添加代码,它确实可以工作:

obj.when_clicked = function object_123(){object_123_Action();my_clicked(obj);};

然而,我不知道这个函数最初的内容是什么,我只想追加:
my_clicked(obj);

我需要obj成为感兴趣的实际对象,即obj本身。

2个回答

4

你可以将它包装起来:

var f = this.when_clicked;
this.when_clicked = function() {
    // Call the original
    var rv = f.apply(this, arguments);

    // your code here

    // Return the original function's return value
    return rv;
};

Function#apply方法使用指定的this值调用原始函数。 arguments由JavaScript引擎提供:它是您的函数被调用时传递的参数的伪数组,因此上述代码只是将所有参数都传递进去。

请务必考虑如果您的函数抛出异常的含义,并在需要抑制异常时捕获它们。

如果您经常这样做,可以给自己创建一个实用函数:

function wrapFunction(f, wrapper) {
    return function() {
        var rv = f.apply(this, arguments);
        wrapper.apply(this, arguments);
        return rv;
    };
}

那么

this.when_clicked = wrapFunction(this.when_clicked, function() {
    // Your code here
});

或者,如果您希望访问原始返回值并可能更改它:

function wrapFunction(f, wrapper) {
    return function() {
        var rv = f.apply(this, arguments);
        rv = wrapper.call(this, rv, arguments);
        return rv;
    };
}

那么

this.when_clicked = wrapFunction(this.when_clicked, function(rv, args) {
    // Your code here, using `rv` and `args`, which is a pseudo-array

    // Potentially update `rv`

    return rv;
});

非常感谢,不幸的是,这个方法没有起作用。也许我应该问如何将一个字符串转换为可执行的函数。字符串应该是 "function when_clicked(){ do_some_action();}"。因此,当我们执行 this.func() 时,do_some_action() 将被运行。谢谢。 - Peter

1
你可以将函数存储在对象的数组中。 然后,在另一个函数中循环这些函数并执行它们。
var myObj = { 'myfunctions': [ ] };

并添加功能:

myObj.myFunctions.push (function () { /*function code here*/ });

或者如果您已经有一个命名函数:

myObj.myFunctions.push (nameOfFunction);

要调用所有函数,请使用此函数(不要将此函数添加到myObj中)

function executeMyFunctions (myObj) {
    for (var i = 0; i  < myObj.myFunctions.length; i++) {
        myObj.myFunctions[i]();
    }
}

我在另一个@peter的问题上使用了这个答案。本意是在这里发布。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接