自分はスーパーJavaScripterでこんなすげーのが5行で書けちゃう。やばいだろ!とかいうのでは全然無いですが、オブジェクト指向っぽい話が最近分かってきたつもりで、それでやっときゃ問題無いってことを思い始めているので、なんかそんな話を書いていきます。
こんな短く書くテクニックがあるぜ! var hoge = hage ? huga : hoga; とか書けちゃうんだぜ!とかより、長くていいから分かりやすく拡張しやすいようにするにはどうするのかとか、そういう話ができればなーと思います。内容的には全くもって新しくも何とも無いですが。jQuery使ってやる前提です。
今日はまんじゅうを5個作ります。なんと、まんじゅうは、クリックすると隠れます。
var Manju = function(){
this.elem;
this.hidden = false;
this.setup();
}
Manju.prototype = {
setup: function(){
this.elem = $('<div class="manju">MANJU!</div>');
$(document.body).append(this.elem);
var self = this;
this.elem.click(function(){
if(self.hidden){
self.show();
}else{
self.hide();
}
});
},
hide: function(){
this.elem.css("background","#cccccc");
this.hidden = true;
},
show: function(){
this.elem.css("background","#000000");
this.hidden = false;
}
}
$(function(){
var manju1 = new Manju();
var manju2 = new Manju();
var manju3 = new Manju();
var manju4 = new Manju();
var manju5 = new Manju();
});
とりあえず解説。
var Manju = function(){
this.elem;
this.hidden = false;
this.setup();
}
まんじゅうを5個作るんですが、その前にまんじゅうの雛型を用意してやりましょう。これをクラスとかいう。(厳密にはJavaScriptではクラスっていう風には言わないんだけれど、ここではまぁ気にしない)
まんじゅうには、まんじゅうを表すHTMLを入れておくelem、まんじゅうが隠れてるのかを表すhiddenっていう箱を用意せよ。まんじゅうは最初は隠れてないのでfalse。そんで、まんじゅうのセットアップをせよ。っていうことをここではしてます。こんな感じで、まんじゅうが作られた時にこれをしてくれっていう関数を、コンストラクタとか言います。まんじゅうクラスを作るには、この、コンストラクタをまず作りましょう。まんじゅうコンストラクタです。
Manju.prototype = {
setup: function(){
…
},
hide: function(){
…
},
show: function(){
…
}
}
次に、まんじゅうの機能をどんどんつけていきます。
今出た、まんじゅうのセットアップ…setupに加え、まんじゅうを隠すhide、まんじゅうを出現させるshowっていう機能をManjuにつけちゃいます。こんな感じで、まんじゅうの機能としてくっつけられた関数のことを、メソッドとか言う。
setup: function(){
this.elem = $('<div class="manju">MANJU!</div>');
$(document.body).append(this.elem);
var self = this;
this.elem.click(function(){
if(self.hidden){
self.show();
}else{
self.hide();
}
});
},
まんじゅうのセットアップでは、まず、まんじゅうを表すHTMLを作ります。
ここからjQueryの便利機能をちょこちょこ使いますが、jQueryの機能は細かく説明しませんので、詳細はjQueryのドキュメントなどを参照してください。はじめに出てくるthisってのは、まんじゅう自体を示します。まんじゅうのelemっていう箱にこのHTMLを入れてしまいます。そんで、ページのbodyに入れ込めっていう命令をかいてあげます。そのあとは、まんじゅうがクリックされた時、隠れてたらまんじゅうのshowメソッドを、隠れてなかったらhideメソッドを実行せよというイベントを、追加したHTMLに設定してあげます。
初めにまんじゅうコンストラクタの中にでthis.setup();って書いてありました。
これは、まんじゅうが作られた時に、このsetupを実行せよってことです。
それで、そのshow,hideってのは何してくれるのかというと…
hide: function(){
this.elem.css("background","#cccccc");
this.hidden = true;
},
show: function(){
this.elem.css("background","#000000");
this.hidden = false;
}
まんじゅうHTMLのCSS、背景を灰色にせよ、黒くせよっていうことをしてくれます。そして、隠れてるのか否かっていうフラグをtrueにしたりfalseにして、いままんじゅうが隠れているのか否かを切り替えます。これでまんじゅうクラスが完成。ついにまんじゅうを作る時が来ました。
$(function(){
var manju1 = new Manju();
var manju2 = new Manju();
var manju3 = new Manju();
var manju4 = new Manju();
var manju5 = new Manju();
});
$(function(){});っていうのは、ページのロードが完了したときにこれやってねっていう命令です。ページがロードされる前にやってしまうと、HTMLがまだ作られていないので、色々と問題になるので、こんな感じで、ロード完了時にまんじゅうを作ってやります。new Manju()です。新しいまんじゅうを雛型からつくってやるのです。こうやって、雛型(クラス)から作られたモノ(オブジェクト)たちを、インスタンスって言います。まんじゅうクラスのインスタンスです。
そんなこんなでまんじゅうが5個できます。
※ まんじゅうクラスを作る時は、雛型を作ってるだっけなので、ロード時じゃなくてもいいのです。
ちなみに、コレ
var self = this;
this.elem.click(function(){
if(self.hidden){
self.show();
}else{
self.hide();
}
});
ようわからんと思った人がいるかもしれませんが、これは、thisっていう変数は、使われる場所でコロコロ変わるものなので、こんな風にかいてあげる必要があります。thisは、まんじゅう自身を指すと言いましたが、clickの中で使われる時は、thisは、クリックされた要素(<div class="manju">MANJU!</div>)がthisになるのです。そんなこんなで、まんじゅう自身を一時的にselfに保存してやり、show、hideメソッドを呼んでやるのです。
まんじゅうには、elemとhiddenっていう箱をつけてやると最初に書きましたが、これら、まんじゅうに属する変数のことを、プロパティって言います。下のようなコードで、中に入ってる情報をとってくることができます。
alert(manju1.hidden); // 隠れてたらtrue、出てたらfalseと出る
this.hiddenとかthis.elemとか使ってましたねそういえば。
こんな感じで、prototypeでメソッドをつけてあげると、メモリを食わなくていいとの話です。各まんじゅうは、elemとhiddenっていう箱だけを持つ形になり、prototypeでくっつけてあげたメソッドは、全まんじゅうで共通になります。
なんかしらのセットにできるものが複数出現する場合は、この、クラスからインスタンスを作っていくという形に落とし込むのが良いです。1個1個を個別に操作できるようになります。
でも、いちいちnewとかしてめんどくさくないですか?まんじゅう100個作れって言われたらかったるいし…。とおもったアナタ。メモリを食う食わないとかいう話よりも、もっと重要な話があります。それは…
---
【参考】
This article is about... JavaScript , jQuery , オブジェクト指向
juner 2009/5/25 (08:27)
その手は…私もよくやります!!
johannes 2009/5/25 (04:14)
待ってた。
Javaのまじめなコードしか読めないので
こういうアプローチを待ってた。
期待してます。
metroider 2009/5/25 (11:16)
ここまでシンプルかつ理解しやすくprototypeを解説してるのは初めてみました。
期待してます!
名無し 2009/5/26 (12:19)
this.elem;
この行は何も代入していないので無意味では?
Takazudo 2009/5/26 (04:06)
な、なんかすごいアクセスありすぎてビビりました・・・
ぼちぼち進めていきたいと思います。
ありがとございます。
>this.elem
これは意味無いですが、
こんだけメンバがいるぞーと最初に書いてるつもりでした。
今考えたら、コンストラクタの中で
this.elemにdiv作って突っ込んでおくべきでした。
これは自分のクセになっちゃってますね。
ご指摘ありがとございます。
kazumeat 2009/5/28 (10:05)
すっごくわかりやすかったです。続編待ってます!
Takazudo 2009/6/10 (02:41)
続き書きました!
よろしくどうぞ!