web-dev-qa-db-fra.com

Ignorer la fonction (par exemple "alerte") et appeler la fonction d'origine?

Je voudrais remplacer une fonction intégrée Javascript par une nouvelle version qui appelle l'original (de manière similaire à remplacer une méthode sur une classe avec une version qui appelle super dans de nombreuses langues). Comment puis-je faire ceci?

Par exemple...

window.alert = function(str) {
    //do something additional
    if(console) console.log(str);

    //super.alert(str) // How do I do this bit?
}
24
user689751

Stockez une référence à la fonction d'origine dans une variable:

(function() {
    var _alert = window.alert;                   // <-- Reference
    window.alert = function(str) {
        // do something additional
        if(console) console.log(str);
        //return _alert.apply(this, arguments);  // <-- The universal method
        _alert(str);                             // Suits for this case
    };
})();

La manière universelle est <original_func_reference>.apply(this, arguments) - Pour conserver le contexte et passer tous les arguments. En règle générale, la valeur de retour de la méthode d'origine doit également être retournée.

Cependant, il est connu que alert est une fonction void, ne prend qu'un seul argument et n'utilise pas l'objet this. Donc, _alert(str) est suffisant dans ce cas.

Remarque: IE <= 8 génère une erreur si vous essayez d'écraser alert, alors assurez-vous que vous utilisez window.alert = ... Au lieu de alert = ....

50
Rob W

Il n'y a pas de "super". Quoi qu'il en soit, créez une fermeture pour "garder" autour de l'objet fonction d'origine.

Notez la "fonction auto-invoquante" qui renvoie un nouvel objet-fonction (qui est affecté à la window.alert propriété). Le nouvel objet-fonction renvoyé crée une fermeture autour de variableoriginal qui correspond à l'original valeur de window.alert qui a été transmis à la "fonction auto-invoquante".

window.alert = (function (original) {
  return function (str) {
    //do something additional
    if(console) {
      console.log(str)
    }
    original(str)
  }
})(window.alert)

Cependant, je crois certains navigateurs peuvent empêcher la modification de alert et d'autres éléments intégrés ...

Codage heureux.

21
user166390

Je suppose que votre question est de savoir comment écraser un intégré et toujours être en mesure de l'appeler. Tout d'abord en tant que clause de non-responsabilité, vous ne devez jamais écraser les inserts intégrés, sauf si vous avez une bonne raison de le faire car cela rendra impossible le débogage/test.

Voici comment vous le feriez:

window._alert = window.alert;
window.alert = function(str) { 
     if(console) console.log(str);
     window._alert(str);
}
5
Art

Comment faire un héritage classique simple en Javascript:

SuperClass.call(this) // inherit from SuperClass (multiple inheritance yes)

Comment remplacer les fonctions:

this.myFunction = this.myFunction.override(
                    function(){
                      this.superFunction(); // call the overridden function
                    }
                  );

La fonction de remplacement est créée comme ceci:

Function.prototype.override = function(func)
{
 var superFunction = this;
 return function() 
 {
  this.superFunction = superFunction;
  return func.apply(this,arguments);
 };
};

Fonctionne avec plusieurs arguments.
Échoue lorsque vous essayez de remplacer des fonctions non définies ou non fonctionnelles.
Transforme "superFunction" en mot "réservé" :-)

2
Poul Krogh

JavaScript n'utilise pas de modèle d'héritage classique. Il y a un Nice article ici qui décrit un moyen d'écrire vos classes afin qu'une syntaxe similaire puisse être utilisée, mais elle n'est pas supportée nativement.

1
David M