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

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

proxyメソッド(2)

proxyメソッドの構文(1)

proxyメソッドを利用すると、thisの内容を自由に設定できるようになります。構文は以下の様にjQuery($)に直接利用できるメソッドとなっており($とproxyの間の.「ドット」を忘れずに)、引数に2つの値を設定します。

proxyの構文(1)
$.proxy(実行するfunction, thisとしたいもの)

サンプルで機能を確認しましょう。サンプル(05/02_01.html)を開き、以下の部分を前回のサンプル(05/01_03.html)と比較して下さい。proxyを利用してnewObjのgetNameFuncを実行するように設定していますが、proxyメソッドの第2引数でnewObjを設定しているので、getNameFunc内のthisはnewObjとして扱われます。

$(function () {
	$("#test").click($.proxy(newObj.getNameFunc, newObj));
});

実際にdivをクリックしてください。前回のサンプル05/01_03.htmlと異なり「Bob」とアラートで表示されます。このようにproxyを利用すれば、ややこしいthisも自分の都合に合わせてコントロールできるのですが、前回の「機能をコピーして設定している」で説明した仕組みについては理解しておくべきです。

proxyの構文(2)

proxyにはもう1つ別の構文があります。とはいえ機能的には同じでthisを自由に設定するだけです。ここで紹介する構文はシンプルですが、第2引数に設定できるfunctionは第1引数に存在するfunctionのみと限定されます(そのため前の構文と異なり、functionの前にオブジェクトを指定しなくても済むのです)。

個人的には、こちらの構文よりも前回の構文の方が混乱しないで利用できます。newObj.getNameFuncとオブジェクトを指定しているので、どこのfunctionを実行しているか把握しやすいのです。

proxyの構文(2)
$.proxy(thisとしたいもの, "実行するfunction")
第2引数のfunctionは第1引数のオブジェクトに存在するfunctionしか設定できません。

こちらの構文のサンプルも用意しました。サンプル(05/02_02.html)を開きjQueryを確認して下さい。注意するのは第2引数のfunction名を(ダブル)クォートで囲むことです。機能的にはサンプル05/02_01.htmlと全く同じで、divをクリックするとBobとアラートで表示します。

$(function () {
	$("#test").click($.proxy(newObj, "getNameFunc"));
});

proxyメソッドの使いどころ

前回のサンプル05/01_03.htmlのようにthisの仕様に混乱した場合にproxyを利用するというのは、あまりお薦めできません(thisの仕様を覚えるべきなので)。ですのでproxyメソッドを利用しないと実現できないようなケースを探してみようと思います。

サンプル(05/02_03.html)を開き、まずは以下の部分を確認して下さい。2つのオブジェクト(newObj_A / newObj_B)を作成し、ともに名前を変数myNameに設定しました。ポイントはnewObj_AにはgetNameFuncを設定しているのに対し、newObj_Bには設定していないことです。

//---オブジェクトA
var newObj_A = new Object();
newObj_A.myName = "Bob";
newObj_A.getNameFunc = function () {
		alert(this.myName);
}
//---オブジェクトB
var newObj_B = new Object();
newObj_B.myName = "John";

続いて以下の部分を確認して下さい。newObj_Aの持つgetNameFuncを、newObj_Bをthisとして実行するように設定しています。その結果divをクリックするとnewObj_BのmyNameであるJohnがアラートで表示されます。

proxyメソッドを利用することで、newObj_BはgetNameFuncを持っていないにもかかわらずnewObj_Aの持つgetNameFuncを利用することができました。

$(function () {
	$("#test").click($.proxy(newObj_A.getNameFunc, newObj_B));
});

似たような複雑な処理を行う場合はあとで研究しようと考えている「クロージャ」や「プロトタイプ」を利用した方が良さそうですが、シンプルな機能の場合はproxyメソッドで充分だと思います。このサンプルでは、まだproxyメソッドのメリットが分からないので、さらにサンプルを考えてみました。

でもproxyメソッドを使わなくても...

サンプル(05/02_04.html)を開いてください。2つのdiv(test_a/test_b)が配置され、jQueryでは以下の様にfuncObjを作成し、そこにwidthFuncを作成して設定しました。widthFuncにはthisの幅を10pxずつ増やす機能を書きました。

var funcObj = new Object();
funcObj.widthFunc = function () {
	this.animate({width: "+=50px"});
}

そして2つのdivをクリックした際にproxyメソッドを利用して、2つのdivのjQueryオブジェクトをthisとして扱うようにしました。これで各divをクリックした際に、thisとして設定したdiv要素の幅が伸びるようになります。

$("#test_a").click($.proxy(funcObj.widthFunc, $("#test_a")));
$("#test_b").click($.proxy(funcObj.widthFunc, $("#test_b")));

これは、なかなか便利に利用できそうな気配がありますが...。サンプル(05/02_05.html)を開いてjQueryを確認して下さい。proxyメソッドを利用しなくても、引数として受け取った対象の幅を伸ばすようなfunctionを作成し、それを実行するようにすれば済んでしまいます。ということでproxyメソッドを研究してみましたが、現時点ではそれほどメリットを見いだせませんでした...。何かよいサンプルが思いついたら加筆しようとおもいます

次はクロージャについて研究してみたいと思います。クロージャはjQueryの仕組みではなくjavaScriptがもとから持っている仕組みですが、大きな可能性を秘めている予感がするのです。