¿Anula la función (por ejemplo, "alerta") y llama a la función original?

Me gustaría anular una función incorporada de Javascript con una nueva versión que llama al original (de manera similar a anular un método en una clase con una versión que llama super en muchos idiomas). ¿Cómo puedo hacer esto?

Por ejemplo...

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

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

preguntado el 03 de mayo de 12 a las 09:05

Un caso similar, pero un poco más complejo: stackoverflow.com/questions/296667/… -

Muestra una alerta superior: stackoverflow.com/questions/1729501/javascript-overriding-alert -

Eliminé las etiquetas "OO" y "superclase" porque no se aplicaban. Pero esta pregunta cubre burlarse de "super" en JavaScript: stackoverflow.com/questions/6885404/javascript-override-methods -

5 Respuestas

Almacene una referencia a la función original en una 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
    };
})();

El camino universal es <original_func_reference>.apply(this, arguments) - Para preservar el contexto y pasar todos los argumentos. Por lo general, también se debe devolver el valor de retorno del método original.

Sin embargo, se sabe que alert es una función nula, toma solo un argumento y no usa el this objeto. Entonces, _alert(str) es suficiente en este caso.

Nota: IE <= 8 arroja un error si intenta sobrescribir alert, así que asegúrese de que está usando window.alert = ... en lugar de alert = ....

Respondido 21 Feb 21, 20:02

Recién probado: Todos los principales navegadores permiten la modificación de la global window.alert, excepto para IE <= 8. Antes de IE 9, se producía un error al intentar sobrescribir alert. - Rob W

@Rob Gracias por el aviso. ¿Notaste el problema de IE con otras funciones integradas? - Ya visto

@ring0 Básicamente cada incorporado: confirm, document, ... Si quieres interceptar window.alert llamadas, puede envolver el código en un cierre donde un personalizado window (o alert) se declara y define la variable. Esto siempre funcionará si su aplicación no se basa en la declaración de variables implícitas. - Rob W

@RobW aunque esta publicación es bastante antigua, solo probé la anulación de alertas en IE 7.0.6002.18005 (Vista) e IE 8.0.6001.18702 (Win XP) y funciona en ambos. - Jeremy S.

@JeremyS. Tienes razón. Cuando escribí esa declaración, usé alert = ..... Esto arroja un error. pero si usas window.alert = ..., entonces todo funcionará según lo previsto. - Rob W

No hay "súper". De todos modos, cree un cierre para "mantener" alrededor del objeto de función original.

Tenga en cuenta la "función de invocación automática" que devuelve un nuevo objeto de función (que se asigna al window.alert propiedad). El nuevo objeto-función devuelto crea un cierre alrededor del variable original que evalúa al original propuesta de of window.alert que se pasó a la "función de invocación automática".

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

Sin embargo, yo CREEMOS algunos navegadores pueden impedir alert y otros incorporados de ser modificados...

Feliz codificación.

contestado el 03 de mayo de 12 a las 09:05

Este es un uso muy elegante de un cierre. Definitivamente la huella de cierre más pequeña que he visto. - cohetes

Supongo que su pregunta es cómo sobrescribe un incorporado y aún puede llamarlo. En primer lugar, como descargo de responsabilidad, nunca debe sobrescribir las funciones integradas a menos que tenga una buena razón para hacerlo, ya que hará que sea imposible depurar/probar.

Así es como lo harías:

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

contestado el 03 de mayo de 12 a las 09:05

Nota: Este enfoque no es fácilmente extensible. Llame al mismo código dos veces y perderá el método original. - Rob W

No si solo configura window._alert si no está definido. - Wesley

Cómo hacer herencia clásica simple en Javascript:

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

Cómo anular funciones:

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

La función de anulación se crea así:

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

Funciona con múltiples argumentos.
Falla al intentar anular funciones indefinidas o no funcionales.
Hace que "superfunción" sea una palabra "reservada" :-)

Respondido 01 Oct 12, 12:10

JavaScript no utiliza un modelo de herencia clásico. hay un lindo artículo aquí que describe una forma de escribir sus clases para que se pueda usar una sintaxis similar, pero no se admite de forma nativa.

contestado el 03 de mayo de 12 a las 10:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.