Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python decorator with javascript

What I want to do is the following :

I have a function that alert something :

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

Now I want to decorate it so that :

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

So then I can write :

myfunction = decorate(myfunction);

And then myfunction will do the normal + log in the console.

How can I make it works with Javascript ?

like image 469
Natim Avatar asked May 03 '12 15:05

Natim


1 Answers

Yes, you can. And in fact, you have, your implementation works perfectly: 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");

I would recommend using function declarations rather than function expressions, though:

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

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

var result = decorate(myfunction);

result("Hi there");

And if you want to create a more generic version, look at using apply (MDN | spec) and the arguments pseudo-array (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);

That version does a couple of things:

  1. Lets you supply the callback as an argument to one central decorate function.

  2. Lets you optionally supply a "context" (this value) to use when calling the callback.

  3. Preserves the value of this when calling both the original and (if you don't supply context) the callback.

...which an be handy when decorating object functions (sometimes called methods).

like image 126
T.J. Crowder Avatar answered Sep 18 '22 06:09

T.J. Crowder