2010-08-04 4 views
21

Dans ce code, j'ai créé une fonction appelée someFunction. Ensuite, j'ai modifié Function.prototype.apply et appel des méthodes. Donc, au lieu de mon code de fonction fonctionne, je cours mon code d'interception (qui montre une alerte). Mais ni "call", ni "apply" n'intercepte un appel de méthode direct. Est-il possible d'intercepter cela?Puis-je intercepter une fonction appelée directement?

Function.prototype.call = function(){alert("call");}; 
Function.prototype.apply = function(){alert("apply");}; 
function someFunction(){} 
window.onload = function(){ 
    someFunction.call(this); //call alert is shown 
    someFunction.apply(this); //apply alert is shown 
    someFunction(); //how can I intercept this? 
} 

Répondre

27

Vous ne pouvez remplacer une fonction connue en définissant une autre fonction à sa place (par exemple, vous ne pouvez pas intercepter tous les appels de fonction):

(function() { 
    // An anonymous function wrapper helps you keep oldSomeFunction private 
    var oldSomeFunction = someFunction; 

    someFunction = function() { 
     alert("intercepted!"); 
     oldSomeFunction(); 
    } 
})(); 

Notez que, si someFunction était déjà un alias/référencé par un autre script avant qu'il ne soit modifié par ce code, ces références indiqueraient que la fonction d'origine ne peut pas être remplacée par la fonction de remplacement.

+0

Peut-être que je peux changer la fonction Function.constructor de sorte que chaque fonction renvoyée aura votre wrapper autour d'elle. – yilmazhuseyin

+2

@yilmazhuseyin: non, vous ne pouvez pas. Changer le constructeur * Function * vous permettrait seulement de remplacer les fonctions créées avec 'new Function (str)'. –

+0

oui vous avez raison. function newConstructor() {alert ("a");}; Function.prototype.constructor = newConstructor; ne fonctionnait pas. – yilmazhuseyin

2

Vous pouvez itérer sur la portée globale et remplacer tous les objets de type fonction que vous trouvez qui ne sont pas "vôtres".

3

Il y a une chance que vous pouvez intercepter la fonction directe appel. Cela nécessite:

  • Soit la fonction est créée par Function.prototype.bind et vous devez écraser Function.prototype.bind avant de créer la fonction, ou
  • La fonction est créée à partir de la fonction() (ou une nouvelle Fonction()) et vous devez également écraser la fonction Fonction avant de créer la fonction cible.

Si aucun des deux ci-dessus peuvent être satisfaits, la seule façon d'intercepter un appel direct est d'envelopper la fonction cible, qui est la solution fournie par AndyE https://stackoverflow.com/a/3406523/1316480

Pour une fonction qui est créé par Fonction littérale et est cachée dans la portée privée, il n'y a aucun moyen d'intercepter un appel direct à elle.

J'ai un billet de blog conclut tous ces: http://nealxyc.wordpress.com/2013/11/25/intercepting-javascript-function/

Questions connexes