2012-05-03 60 views
6

Co chcę zrobić jest następujący:pyton dekorator z javascript

Mam funkcję ostrzegania coś:

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

Teraz chcę urządzić go tak, aby:

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

Więc mogę napisać:

myfunction = decorate(myfunction); 

A następnie mojafunkcja zrobi normalny + log w konsoli.

Jak mogę sprawić, aby działało z Javascriptem?

+2

Właściwie to nie działa tak jak tego – Natim

Odpowiedz

10

Tak, możesz. I faktycznie masz, Twoja implementacja działa idealnie: 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"); 

Polecam przy użyciu funkcji deklaracji zamiast funkcji wyrażenia, choć:

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

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

var result = decorate(myfunction); 

result("Hi there"); 

A jeśli chcesz stworzyć wersję bardziej ogólny, spójrz na użyciu apply (MDN | spec) i pseudoelement arguments (MDN || | 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); 

Ta wersja ma kilka rzeczy:

  1. pozwala dostarczyć zwrotnego jako argument do jednego centralnego decorate funkcji.

  2. Pozwala opcjonalnie podać wartość "context" (this), która ma być używana podczas wywoływania tego wywołania zwrotnego.

  3. Zachowuje wartość this podczas wywoływania zarówno oryginału, jak i (jeśli nie dostarczasz context) wywołania zwrotnego.

... które są przydatne podczas dekorowania funkcji obiektu (czasami nazywane metodami).

+0

zwykle wykorzystać deklarację funkcji, ale w tym przypadku funkcja są zdefiniowane w tablicy (to jest dla StatusCode w $ .ajax ()). Byłbym zadowolony, widząc ogólną wersję. – Natim

+0

@Natim: Co ciekawe, właśnie dodałem jeden. :-) –

+0

Rzecz w tym, że czasami opakowanie może być wywołane przed oddzwonieniem, a czasem po nim. Ale twoja implementacja jest interesująca. – Natim

2

bardziej ogólny używając argumentów i zastosowania:

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

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

var result = decorate(myfunction); 

result("Hi there");