2012-05-03 9 views
6

Lo que quiero hacer es la siguiente:decorador de pitón con javascript

tengo una función que alerta de algo:

myfunction = function(foobar) { 
       alert(foobar); 
      }; 

Ahora quiero decorarla de manera que:

decorate = function(callback) { 
       return function(foobar) { 
        callback(foobar); 
        console.log(foobar); 
      }; 
}; 

Entonces puedo escribir:

myfunction = decorate(myfunction); 

Y luego myfunction hará el + registro normal en la consola.

¿Cómo puedo hacer que funcione con Javascript?

+2

En realidad no funciona así – Natim

Respuesta

10

Sí, puedes. Y de hecho, usted tiene, su implementación funciona perfectamente: Live example | source

var myfunction = function(foobar) { alert(foobar); }; 

var decorate = function(callback) { return function(foobar) { callback(foobar); console.log(foobar); }; }; 

var result = decorate(myfunction); 

result("Hi there"); 

recomendaría función utilizando declaraciones en lugar de la función expresiones, sin embargo:

function myfunction(foobar) { 
    alert(foobar); 
} 

function decorate(callback) { 
    return function(foobar) { 
     callback(foobar); 
     console.log(foobar); 
    }; 
} 

var result = decorate(myfunction); 

result("Hi there"); 

Y si desea crear una versión más genérica, buscar en el uso apply (MDN | spec) y la pseudo-matriz arguments (MDN | spec): Live example | source

function decorate(original, wrapper, context) { 
    return function() { 
     try { 
      original.apply(this, arguments); 
     } 
     catch (e) { 
     } 
     try { 
      wrapper.apply(context || this, arguments); 
     } 
     catch (e) { 
     } 
    }; 
} 

function myFunction(arg1, arg2) { 
    alert("arg1 = " + arg1 + ", arg2 = " + arg2); 
} 

var newFunction = decorate(myFunction, function(arg1, arg2) { 
    console.log("arg1 = " + arg1 + ", arg2 = " + arg2); 
}); 

newFunction(1, 2); 

Esa versión hace un par de cosas:

  1. permite proporcionar la devolución de llamada como un argumento a una función central decorate.

  2. Le permite opcionalmente suministrar un "contexto" (valor this) para utilizar al llamar a la devolución de llamada.

  3. Conserva el valor de this cuando llama al original y (si no proporciona context) la devolución de llamada.

... que es útil cuando se decoran funciones de objeto (a veces llamadas métodos).

+0

lo general el uso declaración de la función, pero en ese caso la función se definen en un array (que es para statusCode en $ .ajax ()). Me alegraría ver una versión genérica. – Natim

+0

@Natim: Curiosamente, acabo de agregar uno. :-) –

+0

La cosa es a veces el contenedor puede ser llamada antes de la devolución de llamada y, a veces después. Pero su implementación es interesante. – Natim

2

Más genérico utilizando argumentos y aplicar:

function myfunction(foobar) { 
    alert(foobar); 
} 

function decorate(callback) { 
    return function() { 
     callback.apply(null, arguments); 
     console.log(arguments); 
    }; 
} 

var result = decorate(myfunction); 

result("Hi there");