Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Web技術勉強会 20111112

873 views

Published on

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Web技術勉強会 20111112

  1. 1. プロトタイプベースOOP ライブラリmix.js Web技術勉強会 2011/11/12Ryuichi TANAKA(@mapserver2007)
  2. 2. mix.jsとは• https://github.com/mapserver2007/mixjs• プロトタイプベースオブジェクト指向プログラミ ングを支援するライブラリ• 親子関係が持てる• 簡単に継承(mix-in)できる• IEでも動く
  3. 3. JavaScriptで継承はやりづらい• 「JavaScript」「継承」とかで検索するとでてくる が、どれも微妙。• A.prototype = new B(); – ありがち – そもそも親子関係になってない• jQuery.extend – プロパティを上書きするだけ – やっぱり親子関係になってない
  4. 4. 継承は親子を作る• 継承というからには親子関係が普通ある• JavaScriptはそれをやるのがすごく大変
  5. 5. とにかく簡単に継承• var obj = A.mix(B)• これだけで継承(mix-in)が完了• とにかく簡単
  6. 6. バグは収束した• mix.jsベースでコードを書き直し中• 動作問題なし• バグはほぼ潰しきった(はず)
  7. 7. 機能を簡単に説明
  8. 8. モジュールを定義する• モジュールという単位でクラスに相当するも のを定義する• モジュールを組み合わせて一つのオブジェク ト(インスタンスに相当)を作る• mix-inした順番通りに親子関係が構築される
  9. 9. モジュールを定義するMixjs.module(“Iphone”, { name: function() { return “iPhone”; }});// Iphone.name();
  10. 10. モジュールを定義するvar namespace = {}:Mixjs.module(“Iphone”, namespace, { name: function() { return “iPhone”; }});// namespace.Iphone.name();
  11. 11. モジュールをmix-inするvar obj = Iphone.mix(Feature);var obj2 = Iphone.mix(Feature).mix(Telephone);var obj3 = Iphone.mix(Feature, Telephone);
  12. 12. 親にしかないメソッドにアクセスvar obj2 = Iphone.mix(Feature).mix(Telephone);// Telephone#getType()にアクセスしたい// Iphone, FeatureはgetType()を持っていないobj2.getType(); // これでOKOKIE以外ではプロトタイプチェーンで取得、IEでは mix-in時に親のメソッドを自身にコピーする
  13. 13. 親にある同じ名前のメソッドにアクセ スしたいvar obj2 = Iphone.mix(Feature).mix(Telephone);// name()はIphone, Feature, Telephone全員が// もっているobj2.name(); // Iphone#name()obj2.parent.name(); // Feature#name()obj2.parent.parent.name(); // Telephone#name()
  14. 14. あらかじめmix-in済みのモジュールを 定義したい• これまでのmix-inは外部mix-in• 外部mix-inはモジュール定義後に動的にmix- inする• モジュール定義時に親子関係が確定してい る場合は静的にmix-inするほうが自然
  15. 15. 静的にmix-in(内部mix-in) Mixjs.module(“Iphone”, { include: Feature, name: function() { return “iPhone”; } });
  16. 16. 静的にmix-in(内部多重継承) Mixjs.module(“Iphone”, { include: [Feature, Telephone], name: function() { return “iPhone”; } });
  17. 17. mix-in済みモジュールか判定var obj = Iphone.mix(Feature);obj.has(Iphone); // trueobj.has(Telephone); //false
  18. 18. 自分自身の参照位置を基底に移動Mixjs.module(“Feature”, { name: function() { // this.name()だと参照できない // this.baseを使うと参照位置を継承済みオブジェクトの最も子供の // 位置に移動させることができる this.base.name(); }});Mixjs.module(“Iphone”, { include: Feature, name: function() { return “iphone”; }});Iphone.parent.name(); // iphone
  19. 19. 同じモジュールはmix-inできない• エラーにはならないが同じモジュールはmix- inできないvar obj = Iphone.mix(Iphone);obj.hasOwnProperty(“parent”); // false
  20. 20. 継承のルール
  21. 21. 1.通常のmix-in• M1 mix M2 M1 -> M2• M1 mix M2 mix M3 M1 -> M2 -> M3
  22. 22. 2.多重継承• M1 mix (M2, M3) M1 -> (M2->M3) # ()内でまずmix-in M1 -> (M2’) M1 -> M2-> M3通常のmix-inのチェーンとはmix-in順が異なる
  23. 23. 3.同じモジュールをmix-in• T1 mix T1 T1
  24. 24. 3.同じモジュールをmix-in• T1 mix T1 T1• T1 mix T2 mix T1 T1 -> T2
  25. 25. 4.mix-in済みモジュールをmix-in• T1 mix (T2 mix T1) mix T1 T1 -> T2’ -> T1 T1 -> T2’ T1 -> T2 -> T1T2’はT2ともT1とも等しくないためこ のようにmix-inされる
  26. 26. 5.同じmix-in済みモジュールが複数 ある場合のmix-inT1 mix (T2 mix T1) mix (T2 mix T1) T1 -> T2’ -> T2’ T1 -> T2’ T1 -> T2 -> T1T2’は2つあるので1つはmix-inさ れない
  27. 27. 6.すべて異なるモジュールだが同じ mix-in順序が含まれるT1 mix (T3 mix T2 mix T1) mix (T2 mix T1) T1 -> T3’ -> T2’ T1 -> T3->T2->T1->T2->T1 Cyclic ErrorT2->T1が繰り返されていると循環参 照エラーとなる。
  28. 28. パフォーマンス測定
  29. 29. 前提条件• 測定環境 – Core2Duo P8700 2.53GHz – Mem 4GB – WindowsVista Ultimate SP2• 実行環境 – Chrome15.0.874.106 m – IE8 – Firefox8
  30. 30. 測定ツール• benchmark.js – http://benchmarkjs.com/• 実行プログラム – https://gist.github.com/1358167
  31. 31. 測定結果 include: [Test1, Test2, Test3] include: [Test1, Test2] include: Test1 IE8(Test1.mix(Test2)).mix(Test3.mix(Test4)) Firefox Chrome Test1.mix(Test2, Test3, Test4) Test1.mix(Test2).mix(Test3) Test1.mix(Test2) 0 0.2 0.4 0.6 0.8 1 1.2
  32. 32. ChromePettern ops/sec msecTest1.mix(Test2) 55,646 0.017971Test1.mix(Test2).mix(Test3) 9,264 0.107945Test1.mix(Test2, Test3, Test4) 13,588 0.073594(Test1.mix(Test2)).mix(Test3.mix(Test4)) 13,639 0.073319include: Test1 11,232 0.089031include: [Test1, Test2] 3,750 0.266667include: [Test1, Test2, Test3] 2,374 0.42123
  33. 33. IE8Pettern ops/sec msecTest1.mix(Test2) 7526 0.132873Test1.mix(Test2).mix(Test3) 1739 0.575043Test1.mix(Test2, Test3, Test4) 3244 0.308261(Test1.mix(Test2)).mix(Test3.mix(Test4)) 2200 0.454545include: Test1 3009 0.332336include: [Test1, Test2] 1338 0.747384include: [Test1, Test2, Test3] 877 1.140251
  34. 34. FirefoxPettern ops/sec msecTest1.mix(Test2) 19123 0.052293Test1.mix(Test2).mix(Test3) 6644 0.150512Test1.mix(Test2, Test3, Test4) 6109 0.163693(Test1.mix(Test2)).mix(Test3.mix(Test4)) 6925 0.144404include: Test1 7437 0.134463include: [Test1, Test2] 3006 0.332668include: [Test1, Test2, Test3] 2661 0.375799
  35. 35. 結論• Chromeで一番速い – まあまあ予想通り• IEは突出して遅い – 予想通りだが内部実装が違うことも多少影響か• includeによる内部mix-inは外部mix-inに比べ極 端に遅い – 改善の余地あり• mix-inチェーンより多重継承でまとめてmix-inす るほうが速い – 要原因調査
  36. 36. まとめ• mix.jsのメリット – 親子関係を構築できる – 簡単 – IEでも動く – 他ライブラリに依存しない• 今後の予定 – mix.jsでアプリを作る – パフォーマンス改善

×