closure sample

Flex(ActionScript)でクロージャーを実装したので、ちょっとメモ。
JavaScriptでの実装とちょっと違っていて?思った以上にはまりました。(汗)

「add1」「add2」のボタン毎に持っている値を「add1」ボタンをクリックした時は「1」加算、「add2」ボタンをクリックした時は「2」加算して画面の「value」ラベル右側(赤字箇所)に表示

add1ボタンを3回クリック後

画面1の状態で、add2ボタンを1回クリック後
(赤字箇所の数値がadd2ボタンを1回しかクリックしていないので「2」と表示)

add1ボタンを3回クリック後

画面3の状態で、add2ボタンを1回クリック後

<!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>
<?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>

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

まだまだ初心者です。記載内容に誤りなどありましたら、ご指摘いただけると嬉しいです。^^;;;