2013-05-09 50 views
0

首先,我的理解是,來自某些語法javascript和actionscript的appart以與函數非常相似的方式運行。在這兩種語言中,我都需要將本地變量添加到某種事件偵聽器。例如,在動作:將一個局部變量添加到動作腳本或JavaScript函數

public class Foo { 
    public function handleBar():void { 
     this.bla(); this.blabla(); 
    } 
    public function createButton():void { 
     SomeSortOfButton button = new SomeSortOfButton(); 

     //HERE COMES THE AWKWARD PART: 
     button.addEventListener(MouseEvent.CLICK, 
      (function (foo:Foo) { 
       return function (event:MouseEvent):void { 
         //I want to do stuff with foo, hence the function that returns a function. 
         foo.handleBar(); 
       }; 
      })(this) 
     ); 
    } 
} 

而且在JavaScript(+ jQuery的)我有這樣的事情,不時:

var foo = ......; 
$("#button").click(
    (function(bar) { 
     return function(event) { 
      //do stuff with bar (which is defined as foo in the first line) 
     }; 
    )(foo) 
); 

我喜歡這樣的工作方式,但對於語法,它是一個完成不行去 imho。有其他選擇嗎?我試圖在動作是使用默認參數的處理程序:

public class Foo { 
    public function handleBar():void { 
     this.bla(); this.blabla(); 
    } 
    public function createButton():void { 
     SomeSortOfButton button = new SomeSortOfButton(); 

     //HERE COMES THE ALTERNATIVE: 
     button.addEventListener(MouseEvent.CLICK, 
      function (event:MouseEvent, foo:Foo = this):void { 
       //I want to do stuff with foo, hence the function that returns a function. 
       foo.handleBar(); 
      } 
     ); 
    } 
} 

但是,這是不允許的,因爲這:美孚=此不能在編譯時解析。公平的,但我仍然想知道,是否有語法糖的上述建設,無論是或JavaScript和動作?我強烈喜歡使用單個函數,而不是返回函數的函數。

我希望答案的形式是:「(據我所知,)通過局部變量」或「是的,你可以做到這一點:... 「。

但當然,任何評論都非常感謝!

+0

很難說出你想達到的目標。在你的JavaScript例子中,你正在通過循環來避免你的事件處理程序使用'foo'。爲什麼?因爲你以後要改變'foo'? – 2013-05-09 09:44:44

+0

如果您在事件處理程序中引用了foo,它位於內部函數的{}內,那麼只有當foo是全局變量時才能使用。而且,foo也可能像你說的那樣變化。 – Herbert 2013-05-09 13:48:36

+0

@ Herbert:不,「foo」不一定是全球性的。它只是在功能定義的範圍內。全局只是這個一般原理的一個特例。更多:[*閉包不復雜*](http://blog.niftysnippets。組織/ 2008/02 /關閉 - 是 - 不complicated.html) – 2013-05-09 14:56:32

回答

1

這是需要"curry" function的經典示例。 Prototype庫有一個,但它很容易推出自己還有:

function curry(func) { 
    var args = Array.prototype.slice.call(arguments, 1); 
    return function() { 
     return func.apply(this, Array.prototype.concat.apply(args, arguments)); 
    }; 
} 

然後,在JavaScript例如:

var foo = ......; 
$("#button").click(curry(function(bar, event) { 
    //do stuff with bar (which has the value of `foo` as of when we hooked up the handler) 
}, foo)); 

ES5具有Function#bind,這是用於設置this值一個功能,但也可以用於咖喱。但是,如果使用Function#bind,則不能讓this剛剛通過(這是以上curry的作用:它調用與調用的值相關的任何this值而不是特定的值)。

這是一般情況。在jQuery的事件處理程序的具體情況,jQuery的爲您提供了一種方式來做到這一點:

var foo = ......; 
$("#button").click({bar: foo}, function(event) { 
    //do stuff, using event.data.bar 
}); 

你必須使用一個對象與click,但如果你使用on相反,可以使用其他的東西。

相關問題