Web技術勉強会 20111112

36
OOP mix.js Web技術勉強会 2011/11/12 Ryuichi TANAKA(@mapserver2007)

description

 

Transcript of Web技術勉強会 20111112

Page 1: Web技術勉強会 20111112

プロトタイプベースOOP

ライブラリmix.jsライブラリmix.js

Web技術勉強会 2011/11/12

Ryuichi TANAKA(@mapserver2007)

Page 2: Web技術勉強会 20111112

mix.jsとは

• https://github.com/mapserver2007/mixjs

• プロトタイプベースオブジェクト指向プログラミングを支援するライブラリ

• 親子関係が持てる• 親子関係が持てる

• 簡単に継承(mix-in)できる

• IEでも動く

Page 3: Web技術勉強会 20111112

JavaScriptで継承はやりづらい

• 「JavaScript」「継承」とかで検索するとでてくるが、どれも微妙。

• A.prototype = new B();

–ありがち–ありがち

–そもそも親子関係になってない

• jQuery.extend

–プロパティを上書きするだけ

–やっぱり親子関係になってない

Page 4: Web技術勉強会 20111112

継承は親子を作る

• 継承というからには親子関係が普通ある

• JavaScriptはそれをやるのがすごく大変

Page 5: Web技術勉強会 20111112

とにかく簡単に継承

• var obj = A.mix(B)

• これだけで継承(mix-in)が完了

• とにかく簡単

Page 6: Web技術勉強会 20111112

バグは収束した

• mix.jsベースでコードを書き直し中

• 動作問題なし

• バグはほぼ潰しきった(はず)

Page 7: Web技術勉強会 20111112

機能を簡単に説明機能を簡単に説明

Page 8: Web技術勉強会 20111112

モジュールを定義する

• モジュールという単位でクラスに相当するものを定義する

• モジュールを組み合わせて一つのオブジェクト(インスタンスに相当)を作るト(インスタンスに相当)を作る

• mix-inした順番通りに親子関係が構築される

Page 9: Web技術勉強会 20111112

モジュールを定義する

Mixjs.module(“Iphone”, {

name: function() {

return “iPhone”;return “iPhone”;

}

});

// Iphone.name();

Page 10: Web技術勉強会 20111112

モジュールを定義する

var namespace = {}:

Mixjs.module(“Iphone”, namespace, {

name: function() {

return “iPhone”;return “iPhone”;

}

});

// namespace.Iphone.name();

Page 11: Web技術勉強会 20111112

モジュールをmix-inする

var obj = Iphone.mix(Feature);

var obj2 = Iphone.mix(Feature).mix(Telephone);

var obj3 = Iphone.mix(Feature, Telephone);

Page 12: Web技術勉強会 20111112

親にしかないメソッドにアクセス

var obj2 = Iphone.mix(Feature).mix(Telephone);

// Telephone#getType()にアクセスしたい

// Iphone, FeatureはgetType()を持っていない

obj2.getType(); // OKobj2.getType(); // これでOK

IE以外ではプロトタイプチェーンで取得、IEではmix-in時に親のメソッドを自身にコピーする

Page 13: Web技術勉強会 20111112

親にある同じ名前のメソッドにアクセスしたい

var obj2 = Iphone.mix(Feature).mix(Telephone);

// name()はIphone, Feature, Telephone全員が

// もっている

obj2.name(); // Iphone#name()obj2.name(); // Iphone#name()

obj2.parent.name(); // Feature#name()

obj2.parent.parent.name(); // Telephone#name()

Page 14: Web技術勉強会 20111112

あらかじめmix-in済みのモジュールを定義したい

• これまでのmix-inは外部mix-in

• 外部mix-inはモジュール定義後に動的にmix-

inする

• モジュール定義時に親子関係が確定してい• モジュール定義時に親子関係が確定している場合は静的にmix-inするほうが自然

Page 15: Web技術勉強会 20111112

静的にmix-in(内部mix-in)

Mixjs.module(“Iphone”, {

include: Feature,

name: function() {name: function() {

return “iPhone”;

}

});

Page 16: Web技術勉強会 20111112

静的にmix-in(内部多重継承)

Mixjs.module(“Iphone”, {

include: [Feature, Telephone],

name: function() {name: function() {

return “iPhone”;

}

});

Page 17: Web技術勉強会 20111112

mix-in済みモジュールか判定

var obj = Iphone.mix(Feature);

obj.has(Iphone); // true

obj.has(Telephone); //false

Page 18: Web技術勉強会 20111112

自分自身の参照位置を基底に移動

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

Page 19: Web技術勉強会 20111112

同じモジュールはmix-inできない

• エラーにはならないが同じモジュールはmix-

inできない

var obj = Iphone.mix(Iphone);

obj.hasOwnProperty(“parent”); // falseobj.hasOwnProperty(“parent”); // false

Page 20: Web技術勉強会 20111112

継承のルール継承のルール

Page 21: Web技術勉強会 20111112

1.通常のmix-in

• M1 mix M2 M1 -> M2

• M1 mix M2 mix M3

M1 -> M2 -> M3M1 -> M2 -> M3

Page 22: Web技術勉強会 20111112

2.多重継承

• M1 mix (M2, M3)

M1 -> (M2->M3) # ()内でまずmix-in

M1 -> (M2’)M1 -> (M2’)

M1 -> M2-> M3通常のmix-inのチェーンとはmix-in順が異なる

Page 23: Web技術勉強会 20111112

3.同じモジュールをmix-in

• T1 mix T1 T1

Page 24: Web技術勉強会 20111112

3.同じモジュールをmix-in

• T1 mix T1 T1

• T1 mix T2 mix T1 T1 -> T2

Page 25: Web技術勉強会 20111112

4.mix-in済みモジュールをmix-in

• T1 mix (T2 mix T1) mix T1

T1 -> T2’ -> T1

T1 -> T2’T1 -> T2’

T1 -> T2 -> T1

T2’はT2ともT1とも等しくないためこのようにmix-inされる

Page 26: Web技術勉強会 20111112

5.同じmix-in済みモジュールが複数ある場合のmix-in

T1 mix (T2 mix T1) mix (T2 mix T1)

T1 -> T2’ -> T2’

T1 -> T2’T1 -> T2’

T1 -> T2 -> T1

T2’は2つあるので1つはmix-inされない

Page 27: Web技術勉強会 20111112

6.すべて異なるモジュールだが同じmix-in順序が含まれる

T1 mix (T3 mix T2 mix T1) mix (T2 mix T1)

T1 -> T3’ -> T2’

T1 -> T3->T2->T1->T2->T1T1 -> T3->T2->T1->T2->T1

Cyclic Error

T2->T1が繰り返されていると循環参照エラーとなる。

Page 28: Web技術勉強会 20111112

パフォーマンス測定パフォーマンス測定

Page 29: Web技術勉強会 20111112

前提条件

• 測定環境

– Core2Duo P8700 2.53GHz

– Mem 4GB

– WindowsVista Ultimate SP2– WindowsVista Ultimate SP2

• 実行環境

– Chrome15.0.874.106 m

– IE8

– Firefox8

Page 30: Web技術勉強会 20111112

測定ツール

• benchmark.js

– http://benchmarkjs.com/

• 実行プログラム

– https://gist.github.com/1358167– https://gist.github.com/1358167

Page 31: Web技術勉強会 20111112

測定結果

include: Test1

include: [Test1, Test2]

include: [Test1, Test2, Test3]

0 0.2 0.4 0.6 0.8 1 1.2

Test1.mix(Test2)

Test1.mix(Test2).mix(Test3)

Test1.mix(Test2, Test3, Test4)

(Test1.mix(Test2)).mix(Test3.mix(Test4))

IE8

Firefox

Chrome

Page 32: Web技術勉強会 20111112

Chrome

Pettern ops/sec msec

Test1.mix(Test2) 55,646 0.017971

Test1.mix(Test2).mix(Test3) 9,264 0.107945

Test1.mix(Test2, Test3, Test4) 13,588 0.073594Test1.mix(Test2, Test3, Test4) 13,588 0.073594

(Test1.mix(Test2)).mix(Test3.mix(Test4)) 13,639 0.073319

include: Test1 11,232 0.089031

include: [Test1, Test2] 3,750 0.266667

include: [Test1, Test2, Test3] 2,374 0.42123

Page 33: Web技術勉強会 20111112

IE8

Pettern ops/sec msec

Test1.mix(Test2) 7526 0.132873

Test1.mix(Test2).mix(Test3) 1739 0.575043

Test1.mix(Test2, Test3, Test4) 3244 0.308261Test1.mix(Test2, Test3, Test4) 3244 0.308261

(Test1.mix(Test2)).mix(Test3.mix(Test4)) 2200 0.454545

include: Test1 3009 0.332336

include: [Test1, Test2] 1338 0.747384

include: [Test1, Test2, Test3] 877 1.140251

Page 34: Web技術勉強会 20111112

Firefox

Pettern ops/sec msec

Test1.mix(Test2) 19123 0.052293

Test1.mix(Test2).mix(Test3) 6644 0.150512

Test1.mix(Test2, Test3, Test4) 6109 0.163693Test1.mix(Test2, Test3, Test4) 6109 0.163693

(Test1.mix(Test2)).mix(Test3.mix(Test4)) 6925 0.144404

include: Test1 7437 0.134463

include: [Test1, Test2] 3006 0.332668

include: [Test1, Test2, Test3] 2661 0.375799

Page 35: Web技術勉強会 20111112

結論

• Chromeで一番速い– まあまあ予想通り

• IEは突出して遅い– 予想通りだが内部実装が違うことも多少影響か

• includeによる内部mix-inは外部mix-inに比べ極• includeによる内部mix-inは外部mix-inに比べ極端に遅い– 改善の余地あり

• mix-inチェーンより多重継承でまとめてmix-inするほうが速い– 要原因調査

Page 36: Web技術勉強会 20111112

まとめ

• mix.jsのメリット

–親子関係を構築できる

–簡単

– IEでも動く– IEでも動く

–他ライブラリに依存しない

• 今後の予定

– mix.jsでアプリを作る

–パフォーマンス改善