closure sample
Flex(ActionScript)でクロージャーを実装したので、ちょっとメモ。
JavaScriptでの実装とちょっと違っていて?思った以上にはまりました。(汗)
- 以下の画面をJavaScriptとActionScriptで実装
「add1」「add2」のボタン毎に持っている値を「add1」ボタンをクリックした時は「1」加算、「add2」ボタンをクリックした時は「2」加算して画面の「value」ラベル右側(赤字箇所)に表示
- 画面1(JavaScript)
- 画面2(JavaScript)
画面1の状態で、add2ボタンを1回クリック後
(赤字箇所の数値がadd2ボタンを1回しかクリックしていないので「2」と表示)
- 画面3(ActionScript)
- 画面4(ActionScript)
- code1(AdderSample.html(JavaScript))
<!DOCTYPE html> <html> <head> <title>Adder Sample(java script)</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="js/libs/jquery/jquery.js" ></script> <script> $(function() { $('#result').text('0'); adder = function(addVal){ var i = 0; // <-- 変数「i」は、add1、add2のボタン毎に保持 return function() { i += addVal; $('#result').text(i); }; }; $('#add1Button').click(adder(1)); $('#add2Button').click(adder(2)); $('#addDiv').click(function(event){ var tmp = $('#history').text(); $('#history').text(tmp + event.target.id + "\n"); }); }); </script> </head> <body> <div style="font-size: 16px; color:blue">Adder Sample(java script)</div> <div> <label>value:</label> <output id="result" style="color: red; font-weight: bold"></output> </div> <div id="addDiv"> <input type="button" id="add1Button" value="add1" /> <input type="button" id="add2Button" value="add2" /> </div> <div style="margin-top: 10px"> <label>click history</label> <br/> <textarea id="history" style="height: 100px;"></textarea> </div> </body> </html>
- code2(Adder.mxml)
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="100" minHeight="100" creationComplete="init()" > <s:layout> <s:VerticalLayout gap="10" paddingTop="10" paddingLeft="10" /> </s:layout> <fx:Style> @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/mx"; #result { color:red; font-weight: bold; } </fx:Style> <fx:Script source="includes/Adder.as" /> <fx:Declarations> </fx:Declarations> <s:Label text="Adder Sample(action script)" fontSize="14" color="blue" /> <s:HGroup gap="5"> <s:Label text="value:" /> <s:Label id="result" /> </s:HGroup> <s:HGroup gap="5" id="addDiv"> <s:Button id="add1Button" label="add1" /> <s:Button id="add2Button" label="add2" /> </s:HGroup> <s:VGroup paddingTop="10"> <s:Label text="click history"/> <s:TextArea id="history" height="100" /> </s:VGroup> </s:Application>
- code3(Adder.as(ActionScript))
add1ボタンで使用している「add」メソッドないでは、「this」は「global object」?なので「this.result.text = String(ix)」では画面に表示されない。
add2ボタンで使用している「addWithObject」メソッドでは、引数に自分自身である「this」を追加し、引数の「objThis」を使用。
import flash.events.MouseEvent; import mx.controls.Alert; private function init():void { this.result.text = "0"; this.add1Button.addEventListener(MouseEvent.CLICK, add(1)); this.add2Button.addEventListener(MouseEvent.CLICK, addWithObject(2, this)); // <-*1*ここで引数にthisを指定 this.addDiv.addEventListener(MouseEvent.CLICK, addHistory); } private function add(addVal:int):Function { var i:int = 0; return function() { // Alert.show(this.toString()); i += addVal; // this does not work because this has object global // this.result.text = String(ix); setValue(i); } } private function setValue(ix:int):void { this.result.text = String(ix); } private function addWithObject(addVal:int, objThis:Object):Function { var i:int = 0; return function(e:MouseEvent):void { i += addVal; objThis.result.text = String(i); // <-- *1*引数で渡されたthisを使って画面表示 } } private function addHistory(event:MouseEvent):void { var tmp:String = this.history.text; this.history.text = tmp + event.target.id + "\n"; }
参考までに
- Alertを使用して「this」を確認
上記実装をgistにアップしました。
Action Script Sample
Java Script Sample
まだまだ初心者です。記載内容に誤りなどありましたら、ご指摘いただけると嬉しいです。^^;;;