JavaScriptのオブジェクト指向について自分メモを書いてみたとか〜
■基本編
忘れないうちに・・・っと。
(2012-01-16)
・④を訂正しました。
①基本
function Class(value){ //コンストラクタ this.property=value; //インスタンスプロパティ this.method=function(){alert(this.property);} //インスタンスメソッド } var c=new Class(value); //インスタンス生成 // c.property; プロパティ利用 // c.method(); メソッド利用
ここでthisでなくてvarじゃだめなのか。と思って調べると
ここ(第101回 JavaScriptで関数をクラスのように使うとき 中にvarと書くかthisと書くかそれが問題だ - bingo_nakanishiの他言語出身者のためのPerl入門)で解説ありました。
②prototypeを使用
上のままではインスタンスごとにメソッド(同じコード)が増える=無駄
また、静的なプロパティ・メソッドもあるので次のようにする
function Class(value){ this.property=value; //インスタンスプロパティ } Class.PROPERTY=VALUE; //クラスプロパティ Class.METHOD=function(){alert(Class.PROPERTY);} //クラスメソッド(this.〜プロパティは使えない) Class.prototype.method=function(){alert(this.property);} //インスタンスメソッド(this.〜が使える)
ここでインスタンスメソッドが複数の場合に記述が面倒
③オブジェクトリテラルの記述で
var obj={ property1:value1, property2:value2, method1:function(){}, method2:function(){}, ・・・ } ↑↓ obj.property1=value1; obj.property2=value2; obj.method1=function(){}; obj.method2=function(){};
を利用して
function Class(value1,value2){ this.property1=value1; this.property2=value2 } Class.PROPERTY=VALUE; Class.METHOD=function(){alert(Class.PROPERTY);} Class.prototype={ method1:function(){alert(this.property1);}, method2:function(){alert(this.property2);} }
④またはこれを使って
function func(value){} ↑↓ var func=function(value){}
var Class=function(value1,value2){ this.property1=value1; this.property2=value2; } Class.PROPERTY=VALUE; Class.METHOD=function(){alert(Class.PROPERTY);} Class.prototype={ method1:function(){alert(this.property1);}, method2:function(){alert(this.property2);} }
■継承編
(2012-01-16)
・⑤をわかりやすくしました。
継承には普通に
・プロパティ: コンストラクタチェーン(call,apply)
・メソッド : プロトタイプチェーン(prototype)
を使います。
ここから始めます。
function SuperClass(value1,value2){ this.property1=value1; this.property2=value2 } SuperClass.prototype={ method1:function(){alert(this.property1);}, method2:function(){alert(this.property2);} }
①callを使用(コメントについては以下同様)
function SubClass(value1,value2,value3){ SuperClass.call(this,value1,value2); this.property3=value3; //SubClass追加のプロパティ } SubClass.prototype=new SuperClass(); SubClass.prototype.method2=function(){alert(this.property2+'sub');} //オーバーライド SubClass.prototype.method3=function(){alert(this.property3);} //SubClass追加のメソッド
②applyを使用
function SubClass(value1,value2,value3){ SuperClass.apply(this,[value1,value2]); this.property3=value3; } SubClass.prototype=new SuperClass(); SubClass.prototype.method2=function(){alert(this.property2+'sub');} SubClass.prototype.method3=function(){alert(this.property3);}
③ここでprototypeを書くのが面倒。でもprototype=でまとめると
最初のSubClass.prototype=new SuperClass()を上書きしてしまい継承されないw
ということで調べると
こちら(JavaScript, apply/call メソッドと prototype 継承 : Serendip – Webデザイン・プログラミング)にありました。
上記に当てはめると・・・
function SubClass(value1,value2,value3){ SuperClass.apply(this,[value1,value2]); this.property3=value3; } SubClass.prototype=new SuperClass(); (function(){ this.method2=function(){alert(this.property2+'sub');} this.method3=function(){alert(this.property3);} }).apply(SubClass.prototype);
④だけどthisも面倒だなあ・・・と思って調べているといろいろありました。
ひとつめ。newを封印して、JavaScriptでオブジェクト指向する(1): Architect Note
ふたつめ。JavaScript におけるクラスの作成と継承 - vivid memo
ついていけませんw今回はそこまで必要としないので。
⑤他の言語のような見易さを考えた結果こうしてみました。
・Function(関数ビルトインオブジェクト)のprototypeにextendメソッドを追加(1回だけ)
Function.prototype.extend=function(SuperClass,subMethod){ this.prototype=new SuperClass();//Superクラスのprototypeメソッドチェーン設定 for(name in subMethod){ this.prototype[name]=subMethod[name];//追加メソッド・オーバーライド分をコピー } }
・あとはこういう形で記述できます。
function SubClass(value1,value2,value3){ SuperClass.apply(this,[value1,value2]); this.property3=value3; } SubClass.extend(SuperClass,{ method2:function(){alert(this.property2+'sub');}, method3:function(){alert(this.property3);} });
(収穫)
・今回の件でこんなこともできると知りました。
Function.prototype.hyouji=function(mes){ alert("Hello "+mes); } var a=function(){}.hyouji("world!"); ↑↓ function b(){} b.hyouji("work!");
・ただしこんなことはできませんでした。
Function.prototype.METHOD=function(){ alert("Hello"); } function Class(){} var instance=new Class();//Classのインスタンス instance.METHOD();//エラー(METHODはクラスメソッド扱い?)