2011-12-12 3 views
0

Donc, j'ai fait ce code pour m'aider à ajouter des fonctions après ou avant d'autres fonctions, mais je ne pouvais pas trouver une meilleure façon de le faire, je devais utiliser eval() et c'est vraiment pas une bonne pratique. Au début, j'ai essayé de faire quelque chose comme:Quelque chose d'orienté en Javascript

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 

mais cela n'a pas fonctionné puisque la fonction ne peut pas changer elle-même. Donc, je l'ai fait:

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! 

je ne veux pas travailler avec des objets ou quoi que ce soit, je veux juste ajouter plus de code avant ou après ma fonction déjà déclaré

+0

Notez également compter sur votre 'Function.prototype.toString' retourner quelque chose de sensé, il ne sera pas. – Raynos

Répondre

0

J'ai une bibliothèque utilitaire appelé fcombine qui prend en charge

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

La raison pour laquelle votre code est moche est que vous ne renvoyez pas la nouvelle fonction.

Le problème avec votre code est aussi qu'il utilise eval et essaie de faire trop de magie. L'idée de passer dans une chaîne de noms de variables, puis d'évoquer cela est absolument horrible.

Vous pouvez écrire assez facilement

hello = Aspects.append(hello, new_function);

Comme l'a démontré fcombine.post

+0

merci, ouais je pense que je vais devoir abandonner un peu de magie et retourner la nouvelle fonction. Votre bibliothèque semble très utile, merci. –

-1

Qu'en est-ce,

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 

juste pour montrer l'approche, de la fonction parent window peut également être un argument facultatif à la fonction fnAppend. Il suffit de changer l'ordre vous donnera 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); 
    } 
} 
+0

Cela ne fonctionne que pour les variables globales. Ce qui en fait une solution inutile car les globals doivent être évités à tout prix. – Raynos

+0

cela ne fonctionne pas sur Node.JS par exemple parce que je n'ai pas la fenêtre, c'est pourquoi j'ai utilisé eval(), savez-vous s'il y a quelque chose qui pourrait le remplacer? –

Questions connexes