- 2008-06-11 (水)
- 技術
prototype.jsと違ってjQueryはメソッドを呼ぶたびにjQueryオブジェクトを返します。
なのでオブジェクト汚染がないのがメリットですが、クラスの定義の仕方がちょっぴりトリッキーだったのでメモメモ。
prototype.jsのクラス定義
var Class = {
create : function () {
//オブジェクトをリターン
return klass;
}
};
これは比較的JavaScripterにとっては安心できるコードですね。
クラスという変数に連想配列を入れてあたかもクラスのように見せています。
Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
initialize : function (element) {
this.element = $(element);
}
}
こっちは上で紹介したClass.create()を使ってオブジェクトを取得し、そのprototypeにメソッドを追加していっています。
こっちのほうがプロトタイプベースな感じが出ててJavaScript~!って感じがします。
jQuery.jsのクラス定義
jQueryを見てみると初めに
(function () {
/*
* jQuery 1.2.6 - New Wave Javascript
*
* Copyright (c) 2008 John Resig (jquery.com)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
* $Rev: 5685 $
*/
という部分がありますが、一見普通のコメントか~と思っていると1行目になんかいる!
そう、匿名関数(無名関数)ですね。
つまり、jQuery.jsの全体をこの匿名関数で覆われていて、一番最後の行(3549行目)で実行しています。
});}) (); ←ここですね。
なかなかいやらしいですね。
ではjQuery.jsのコードはかなり長いので比較的コンパクトにまとめてみました。
以下がそれです。
(function () {
var jQuery = window.jQuery = window.$ = function (ele) {
return new jQuery.fn.init(ele);
};
jQuery.fn = {
//jQuery Instance
init : function (ele) {
this.prop = ele;
}
, alert : function (x) {
window.alert(x);
}
}
jQuery.fn.init.prototype = jQuery.fn;
}
)();
分かりやすくするためにコードを簡単にしていますが、大体こんな感じでしょう。
これを実行するには普通にjQueryを使う感じで実行できます。
$().alert("hogehoge");
初めの$()でjQueryのオブジェクトが返ってくるので、後はメソッド定義されているalertを呼び出せば実行できるという感じです。
ただこのコードにはjQueryらしいスパイスがふんだんに盛込まれているのでちょっと説明してみましょう。
jQueryにアクセスする方法
まずjQueryは全体を匿名関数で覆われています。ということはスコープは関数の中で終わってしまいますね。(すげ~)
では外からアクセスするにはどうするのでしょう?
それは以下のコードが示してくれてます。
var jQuery = window.jQuery = window.$ = function (ele) {
ここでwindowオブジェクトに詰めています。これで匿名関数の外側からでもアクセスできるんですね!
jQuery()と$()でアクセスできるようです。
jQueryオブジェクトの取得方法
素直に
return jQuery(ele);
となっていたら理解しやすいですが、実際のコードは以下。
var jQuery = window.jQuery = window.$ = function (ele) {
return new jQuery.fn.init(ele);
};
う~ん、jQueryの右側になんかいる。(.fn.init)
まぁ難しく考えないでもしもjQuery()とした場合とjQuery.fn.init()とした場合にはそんなに違いがないと考えちゃいましょう。
というのももしjQueryのオブジェクトを返す方法がjQuery()だとしたらjQueryの型はfunctionになりますね、んで実際のjQueryオブジェクトの返し方はjQuery.fn.init()なのでinit()の型がfunctionということになります。結果的にはfunction型をnewしてObject型を生成しているのでどっちもおんなじ感じです。
だからあんまり違いはないっす。
jQueryのメソッドはどこにセットされてるの?
先ほどinitコンストラクタがnewされると書きましたが、ここがミソです。
つまりjQueryというオブジェクトの正体はこのinit()なんです。initというfunctionオブジェクトがjQueryオブジェクトの正体というのにはちょっと違和感がありますが、どうやらそのようです。
ただこのinitが返すjQueryオブジェクトをそのまま使っても、
alert : function (x) {
window.alert(x);
}
このalertメソッドは呼べません。ここがまた難しいところ。
ちょっと一般的にオブジェクトを生成してみましょう。
var init = function () {
}
init.prototype = {
alert : function (x) {
window.alert(x);
}
}
window.$ = window.jQuery = function () {
new init();
};
こう書くとよく分かりますね。
まずinitオブジェクトのprototypeにalertをセットして、functionオブジェクトをnewしてjQuery変数にセットしています。
つまりinitのprototypeにalertは別にセットする必要がありますね。
なので先に書いた簡易版jQueryコードのalertメソッドはそのままでは使えません。
これを使えるようにしているのが、
jQuery.fn.init.prototype = jQuery.fn;
ここです。jQueryのコードでは529行目です。
ここでinitのprototypeにメソッドがたっぷり所属しているjQuery.fnをセットしています。これで呼べるようになるわけです。
かっちょいい~!
さすが「jQuery 1.2.6 - New Wave Javascript」と書いてあるとおりです。
- Newer: JavaScriptでリフレクション
- Older: ActionScriptでクロージャを使う方法
Comments:0
Trackback:0
- TrackBack URL for this entry
- http://hisasann.com/cgi-bin/mt/mt-tb.cgi/1036
- Listed below are links to weblogs that reference
- jQueryのクラス定義はトリッキーでかっこいいよ from HouseTect, JavaScripter Blog


