初心者向けのjQuery入門講座|デザイナー向けのJavaScriptライブラリ

このエントリーをはてなブックマークに追加
索引
1章:jQuery入門
2章:jQuery基礎
3章:jQuery発展
番外編:研究

クロージャ(3)

概要

引数を利用する

クロージャは引数を利用することで、より汎用的に利用できます。またインスタンスの作成時に引数を利用することで、同じオリジナルから異なるインスタンスを作成する事ができるので、似たような処理を管理するのに役立ちそうです。

解説

引数を利用する

クロージャ(オリジナル)に作成したfunctionは引数を受け取るようにできます。
サンプル(closure3/01.html)のソースを開き、オリジナルの作成部分を確認して下さい。

下記ソースの5行目、countUpの機能を設定しているfunctionの( )内に変数iが追加されているのを確認して下さい。この変数iで、送られてくる引数を受け取ります。受け取った引数は6行目で利用され、カウント用の変数cntに加算されます。つまりカウントは引数で渡された分だけ増加します。

//---クロージャ(オリジナルの作成)
function countMaster() {
	var cnt = 0;
	var myObj = new Object();				
	myObj.countUp = function (i) {
		cnt += i;
		$(".cnt").text(cnt);
	}
	myObj.getCnt = function () {
		return cnt;
	}
	return myObj;
}

次はcountUpに引数を送っている部分を確認します。以下の様にupボタンをクリックしたときに実行するcountUpで引数10を渡すようにしました。そのため、このサンプルではupボタンをクリックするとカウントが10ずつ上がっていくのです。

$(".up").click(function () {
	cntObj.countUp(10);
})

このようにクロージャ内で作成したfunctionも引数を利用することが可能です。

インスタンス作成時にも引数を利用

インスタンス作成時にも引数を利用することが可能です。サンプル(closure3/02.html)を開いてオリジナルの作成部分を確認して下さい。以下1行目のように変数selectorで引数を受け取るようにしました。ここではセレクタを受け取る予定なので、2行目でjQueryオブジェクトに変換して変数myTargetに代入します。

そして7行目で実際にmyTargetを利用しました。ここではtextメソッドを利用して指定した要素にカウンタの数字を表示するので、このサンプルではインスタンス作成の際に受け取ったセレクタの要素にカウンタを表示します。

function countMaster(selector) {
	var myTarget = $(selector);
	var cnt = 0;
	var myObj = new Object();
	myObj.countUp = function (i) {
		cnt += i;
		myTarget.text(cnt);
	}
	myObj.getCnt = function () {
		return cnt;
	}				
	return myObj;
}

続いてインスタンス作成の部分を確認して下さい。以下の様にcountMasterを実行する際に引数で「.cnt」を渡すようにしました。このためcntクラスの付いた要素にカウンタの数字を表示するようになるというわけです。

//---クロージャ(インスタンスの作成)
cntObj = countMaster(".cnt");

インスタンスが1つしかないとメリットが確認できないので、次項では複数のインスタンスを作成したサンプルを紹介します。

複数のカウンタを操作

クロージャは複数の似たような機能をコントロールするのに役に立ちます。これまでのサンプルではカウンタが1つのため、クロージャを利用するメリットがありません。ですのでサンプル(closure3/03.html)では複数の要素にそれぞれカウンタの機能を付けました。まずはソースを確認してbody内にカウンターのセットが2つあることを確認してください。2つのカウンターはid属性によってteam_Aとteam_Bに分けられています。

<div id="team_A">
	<div class="cnt">0</div>
	<button class="up">count up</button>
	<button class="disp">watch</button>
</div>
<br><br><br><br>
<div id="team_B">
	<div class="cnt">0</div>
	<button class="up">count up</button>
	<button class="disp">watch</button>
</div>

続いてjQueryを確認します。まず着目するのはオリジナルの作成部分です。ここはサンプルclosure3/02.htmlから変更ありません。クロージャは完成させてしまえば、オリジナルのソースを変更することはほとんどありません。変更しているのは利用する部分です。

インスタンスを作成しているのは以下の部分です。2行目で初期化の設定をしています。ここでteam_Aのidに囲まれた方の.cntを引数で設定したので、返値として受け取ったcntObj_Aを操作するとteam_Aのcntにカウンタが表示されます。そして実際にcntObj_Aを利用する部分は4行目と7行目です。

//------------TEAM A
cntObj_A = countMaster("#team_A>.cnt");
$("#team_A>.up").click(function () {
	cntObj_A.countUp(10);
})
$("#team_A>.disp").click(function () {
	var cnt = cntObj_A.getCnt();
	alert(cnt);
})

ここでサンプルclosure3/02.htmlと比較して、上記の赤字の部分以外はすべて変更がないことを確認して下さい。クロージャは完成させてしまえばインスタンスも、ほとんど変更無しで利用できるのです。そしてteam_Bの方も上記赤字の部分が異なっているだけです(countUpの引数には5を設定しました)。

このサンプルのポイントはteam_Aとteam_Bのカウンタがそれぞれ独立して機能している点です。カウンターの変数cntは共通のハズなのに2つのカウンタが干渉するようなことはありません。これを利用すればflashのムービークリップのように利用できそうなので、引き続き研究する予定です。