附加代码到现有的函数的末尾(Append code to the end of an existin

2019-07-30 03:11发布

我需要触发函数bar()每当函数foo()火灾。 我有超过函数foo或者它是否会在未来的变化无法控制。 我经常有这种情况(我恨它)。

我写了这个功能,我的代码添加到函数foo的结尾:

function appendToFunction(fn,code){ 
if(typeof fn == 'function'){
    var fnCode = fn.toString() ;
    fnCode = fnCode.replace(/\}$/,code+"\n}") ;
    window.eval(fnCode);                    // Global scope
    return true ;
}
else{
    return false ;
}
}

例如:

appendToFunction(foo,"bar();");

这在我看来是一个可怕的想法 - 但它的作品。 有人能指出我在一个更好的(更安全)的方向吧。

编辑: foo不是一个特定的功能,但很多功能,我清盘处理。 他们没有在页面动态变化。 但是,他们可能会改变(例如,表单验证需求)不时。

解决方案 :我对亚当的回答修改后的版本解决。 它并不完美,但它是比我有更好的:

var oldFoo = foo ;
foo = function(){
        var result = oldFoo.apply(this, arguments);
        bar();
        return result ;
}

NB。 当心在IE6 / 7一些本地函数没有一个.apply()方法。

Answer 1:

你可以只覆盖foo与调用原始的自定义功能。

var old_foo = foo;
foo = function() {
  old_foo();
  bar();
}

你也应该传递任何参数foo通过您的替换功能考虑到它。



Answer 2:

function extend(fn,code){
  return function(){
    fn.apply(fn,arguments)
    code.apply(fn,argumnets)
  }
}

并使用它像这样:

function appendToFunction(fn,code){ 
    if(typeof fn == 'function'){
        var fnCode = fn.toString() ;
        fnCode = fnCode.replace(/\}$/,code+"\n}") ;
        window.eval(fnCode);                    // Global scope
        return true ;
    }
    else{
        return false ;
    }
}

appendToFunction = extend(appendToFunction,function(){/*some code*/});

这会给你“这”两个功能相同



Answer 3:

你可以做这样的事情: 演示

function foo() {
 console.log('foo');
}

function appendToFunction(fn, callback) {
  window[fn] = (function(fn){
    return function() {
      fn();
      callback();
    }
 }(window[fn]));
}

appendToFunction('foo', function(){console.log('appended!')});

foo();


Answer 4:

嗯,这涉及我也,你提到

我经常有这种情况(我恨它)。

你介意我在什么情况下该保持发生问吗? 它是在企业规模,还是在个人项目的范围有多大? 你已经清楚地得到了一个水平头你的肩膀,并知道你在做什么是不寻常的,所以我不知道如果有一个交替的解决方案。

我想问的原因是, 这种做法可能会打开的问题即可。 如果foo例如失败,或者如果foo返回一个值中期评估? 通过简单的附加bar ,以实际功能并不保证它会执行。 预未决它在另一方面意味着它容易执行,但仍然在我看来,是不是一个好方法。

你有没有考虑修订功能foo ? 我知道,这似乎是一个愚蠢的问题,但如果你遇到类似的整个问题,它可能是值得的。 如果你想保持抽象的东西,你可以采取“事件处理”的方式,因此foo触发一个事件window ,这反过来然后触发bar ,你的情况,将这项工作。

或者,如果你知道foo是,和它做什么,你可以挂接到它的原型,如果它是一个对象,然后适当地修改代码出现。 但是你没有提到这个功能是开放的变化,这可能使该选项多余的,但它是一个可能的解决方案仍然。



Answer 5:

您可以追加或预先准备一些新的代码,以现有的功能,只使用例如合并它们:

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);
    }
}



一个基本的例子是以下几点:

// 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



需要注意的是合并函数试图预期“这个”适用于合并后的部分,否则,你可以只是简单的传递希望“这个”给他们,以及你可以处理的相对参数。
一个更普遍的例子可能是以下几点:

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


文章来源: Append code to the end of an existing function