質問

So, i made this code to help me add functions after or before other functions, but i couldn't figure out a better way to do that, i had to use eval() and that is really not a good practice. At first, i tried to do something like:

Function.prototype.append = function(fn){
    eval("this = function(){ ("+this.toString()+").apply(this, arguments); fn.apply(this, arguments); }");
}

hello = function(){
    console.log("hello world!");
}

hello(); // hello world!
hello.append(function(){
    console.log("bye world!");
});
hello(); // hello world! bye world

but it didn't work since the function can't change itself. So i did this:

Aspects = new Object();

Aspects.append = function(aspect, fn){
    eval(aspect + " = function(){ ("+eval(aspect + '.toString()')+").apply(this, arguments); fn.apply(this, arguments); }");
}

Aspects.prepend = function(aspect, fn){
    eval(aspect + " = function(){ fn.apply(this, arguments); ("+eval(aspect + '.toString()')+").apply(this, arguments); }");
}

hello = function(){
    console.log("hello world!");
}

hello(); // hello world!

Aspects.append('hello', function(){
    console.log("bye world!");
});

hello(); // hello world! bye world!

i don't want to work with objects or anything, i just want to add more code after or before my already declared function

役に立ちましたか?

解決

I have a utility library called fcombine which supports

f1 = fcombine.pre(new_function, f1);
f1 = fcombine.post(f1, new_function);

The reason your code is ugly is because your not returning the new function.

The problem with your code is also that it uses eval and tries to do too much magic. The whole idea of passing in a string of a variable name then evalling that is absolutely horrible.

You can quite easily write

hello = Aspects.append(hello, new_function);

As demonstrated by fcombine.post

他のヒント

what about this,

function fnAppend(old_fn_name, new_fn){
    var old_fn = window[old_fn_name];
    window[old_fn_name] = function(){
        old_fn();
        new_fn();
    }
}

hello = function(){
    console.log("hello world!");
}

hello(); // hello world!
fnAppend('hello', function(){
    console.log("bye world!");
});
hello(); // hello world! bye world

just to show the approach, the function parent window can also be an optional argument to the fnAppend function. Just changing the order will give you fnPrepend


EDIT

function fnAppend(old_fn_name, new_fn, obj){
    obj = obj || window;
    var old_fn = obj[old_fn_name];
    obj[old_fn_name] = function(){
        old_fn.apply({},arguments);
        new_fn.apply({},arguments);
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top