Más contenido relacionado
Web技術勉強会 20110528
- 1. Web技術勉強会
2011/05/28
Ryuichi TANAKA/@mapserver2007/summer-lights.jp
JavaScriptでプロトタイプベースオブジェクト指向プログラミング
~続・親子関係を維持してクラスを使わないオブジェクト指向プログラミング手法~
- 2. 前回の内容
簡単に継承
var obj = Base.mix(Utils).mix(Http);
mixメソッドで簡単にモジュールをMix-in
親子関係を維持した継承
obj.parent().getName();
子と親で同じメソッドがあった場合、従来の継承では上書きされ
てしまうため親メソッドにアクセス不能だったが、parent()経由
でアクセス可能にした
- 9. 前回の問題点①を解決
var Iphone = Module.create({
getPhoneName: function() {
return “iphone”;
}
});
// alert(Iphone.hasOwnProperty(“mix”)); // true
// alert(Iphone.hasOwnProperty(“parent”); // true
// Feature, Telephoneも同様に定義
var obj = Iphone.mix(Feature).mix(Telephone);
alert(obj.parent().getPhoneName()); // garake-
var obj2 = Iphone;
alert(obj2.parent().getPhoneName()); // undefined method
- 10. 前回の問題点②
IE未対応
趣味なら問題ない(公開してるシステムはほとんどIE未対
応)
だが、個人的な野望として仕事で使いたいと密かに思っ
てるのでこれはなんとかしたい。
仕事ではIEだらけ。避けて通れない…。
ライセンスさえクリア出来れば仕事でも使える。
とはいえ簡単じゃない
モダンブラウザでできた__proto__による継承関係、プ
ロトタイプチェーンを利用した親のメソッド自動探索が
使えない。つまりこれを自前で作らないといけない。
この問題が今回の最難関
- 12. 単独Mix-inオブジェクトを親にしたMix-inパターン
var obj = Iphone.mix(Feature)
obj.mix(Telephone)
単独Mix-inオブジェクトを子にした多重継承パターン
var obj = Iphone.mix(Feature)
Telephone.mix(obj, Android)
多重継承オブジェクトを親にしたMix-inパターン
var obj = Iphone.mix(Feature, Telephone)
obj.mix(Android)
多重継承オブジェクトを子にした多重継承パターン
var obj = Iphone.mix(Feature, Telephone)
Android.mix(obj, Ipad)
- 13. 実装方法について(__proto__の代用)
Iphone.mix(Feature).mix(Telephone)
② オブジェクト探索は
Iphone プロトタイプチェーンをと同じこと。
①
Feature 探索処理を自前で実装した。
parent()
③
getPhone parent() Telephone
Name()
getPhone
Name() parent()
getPhone
Name()
①:子(Iphone#parent)は親(Feature)オブジェクトを指すようにする
②:①で一つのオブジェクトとして扱う
③:②のオブジェクト(parentの指す先を探し続ける)を探索して一番親
のオブジェクト(Feature#parent)を見つけて、その親(Telephone)を
指すようにする
- 14. 実装方法について(プロトタイプチェーンの代用)
var obj = Iphone.mix(Feature).mix(Telephone)
obj.getType() // Telephone#getType
obj Iphone
Feature ④
parent() parent()
③ parent()
getPhone getPhone
① Name() getPhone
Name() Telephone
Name()
getType() getType()
getType() parent()
getPhone
Name()
②
getType()
①:objにコピーする
②:子は親(祖先)を辿り、子にないメソッドがあればobjにコピーする。かつ、親は
その親(祖先)を辿り、親にないメソッドがあれば親にコピーする。
③:親を辿り、すでに子にコピー済みのメソッドであればコピーしない
④:parent()はコピーしない(mix()も同様)
- 16. 前回未実装機能を実装
多重継承
obj = Iphone.mix(Feature, Telephone);
実装自体は非常に簡単に完了
引数を可変にするだけ。arguments.length回同じことをする
だけ。
- 17. Mix-in、多重継承したオブジェクトを再継承する
機能
Mix-inしたオブジェクトを継承対象にする
obj = Iphone.mix(Feature).mix(Telephone);
obj2 = Android.mix(obj);
obj3 = obj2.mix(Ipad)
多重継承したオブジェクトを継承対象にする
obj = Iphone.mix(Feature, Telephone);
obj2 = Android.mix(obj, Ipad);
obj3 = obj.mix(Android, Ipad);
既存の継承機能を少し拡張することで対応。そんなに難
しくなかった。
- 20. 主要JavaScriptライブラリとの比較
jQuery prototype.js Ext.js mix.js
継承方法 プロパティ クラスベース クラスベース プロトタイプベース
上書き
親子関係 ☓ ☓ ☓ ○
の維持
親の呼び 呼び出し不 Super.prototyp Super.supercla obj.parent().getNa
出し方 可 e.getName.appl ss.getName.ap me()
y(this) ply(this,
arguments)
継承の仕 var obj = var obj = var obj = var obj =
方 $.extend(o Object.extend(c Ext.extend(cls1, o1.mix(o2)
1, o2) ls1, cls2) cls2)
メリット シンプル 馴染みある継承 馴染みある継承 シンプル
方法 方法
デメリッ 親を呼び出 親の呼び出し方 親の呼び出し方 オブジェクトにmix,
ト すことが出 が長い が長い parentが実装される
来ない