2012-05-03 86 views
6

我想要做的是以下幾點:用JavaScript蟒蛇裝飾

我有警覺的東西功能:

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

現在我想裝飾一下,這樣:

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

那麼我可以這樣寫:

myfunction = decorate(myfunction); 

然後myfunction將在控制檯中執行正常的+日誌。

我該如何使它適用於Javascript?

+2

其實它的工作是這樣 – Natim

回答

10

是的,你可以。事實上,你有,你的實現完美工作: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"); 

我會建議使用功能聲明而不是功能表達,雖然:

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

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

var result = decorate(myfunction); 

result("Hi there"); 

如果你想創建一個更寬泛的版本,看看使用applyMDN | spec)和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); 

這個版本做了幾件事情:

  1. 允許您提供回調作爲參數傳遞給一箇中央decorate功能。

  2. 允許您選擇提供調用回調時使用的「上下文」(this值)。

  3. 當調用原始和(如果您不提供context)回調時保留值this

...這在裝飾對象功能(有時稱爲方法)時很方便。

+0

我通常使用函數的聲明,但是在這種情況下,功能是一個數組中定義(這是在的StatusCode $阿賈克斯( ))。我很樂意看到一個通用版本。 – Natim

+0

@Natim:奇怪的是,我剛剛添加了一個。 :-) –

+0

事情有時包裝可能會在回調之前調用,有時會在之後調用。但是你的實現很有趣。 – Natim

2

更通用的使用參數和應用:

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

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

var result = decorate(myfunction); 

result("Hi there");