defjs をひも解く

3,067 views

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,067
On SlideShare
0
From Embeds
0
Number of Embeds
519
Actions
Shares
0
Downloads
10
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

defjs をひも解く

  1. 1. def.js をひも解く ~オレ標準 js 記法~ id:mooz @stillpedant
  2. 2. 自己紹介 • 名前 – mooz (Hatena, GitHub, …) – stillpedant (Twitter, Google) • 好きな言語 – Mozilla 系 JavaScript • 作ったもの 近影 – KeySnail (Emacs 版 Vimperator) – MiSPLi (Lisp 処理系 in JavaScript) – その他もろもろ 詳しくは http://mooz.github.com/index-ja.html で
  3. 3. def.js
  4. 4. def.js • http://github.com/tobeytailor/def.js • Ruby に似た記法でクラス定義と継承が行える
  5. 5. サンプルコード
  6. 6. サンプルコード !?
  7. 7. 説明 • def (クラス名) (定義); – クラス定義 – def ("Person") ({ … }); • def (クラス名) << 親クラス(定義); – 親クラスを指定したクラス定義 (継承) – def (“Ninja") << Person({ … }); • this._super(); – メソッド中から用いる – 親クラスの同名メソッドを呼び出し
  8. 8. サンプルコード (再掲)
  9. 9. 今回のスライドの目的 • def.js の挙動を理解する • def (クラス名) (定義); • def (クラス名) << 親クラス(定義); • this._super();
  10. 10. def (クラス名) (定義);
  11. 11. def (クラス名) (定義); • def 関数は関数 (deferred) を返す • def(“Person”) とすると – Person クラスが作成され (window.Person が 定義される) – 「定義 (props) を使って Person クラスを拡 張する関数」が返る • つまり def(“Person”)({ … }); とすると – Person クラスが定義され, { … } を使ってその クラスが拡張される ※ “拡張” : メソッドやプロパティを定義すること
  12. 12. def (クラス名) << 親クラス(定義);
  13. 13. def (クラス名) << 親クラス(定義); • 前述の通り def 関数は関数 deferred を返す • この関数には valueOf というプロパティが設定 されている • この valueOf がミソ
  14. 14. valueOf • オブジェクトをプリミティブ値に変換する際に 呼ばれる • プリミティブ値が期待される場面にオブジェク トが出くわしたとき自動的に呼ばれる
  15. 15. valueOf の挙動 実行すると, 1. def(foo) called 2. def(bar) called 3. foo (valueOf) 4. bar (valueOf)
  16. 16. def (クラス名) << 親クラス(定義); • def 関数は valueOf の設定された関数 deferred を返す • def (クラス名) << 親クラス(定義); とすると合 計で 3 回関数が呼ばれる def (クラス名) 親クラス(定義) dererred.valueOf (def の返り値)
  17. 17. def(“Ninja”) << Person({ … }); def(“Ninja”) << Person({ … }); としたとき…… def(“Ninja”) 1. Ninja クラスを作成 2. deferred.valueOf を設定 3. deferred を返す def.js のコンテキスト内でグローバル _super, _props を設定 deferred Person({ … }); def(“Ninja”) の返した deferred に valueOf が 設定されているので…… 1. deferred の _super に Person を設定 2. deferred の _props に { … } を設定 deferred.valueOf 1. deferred の _props を使い Ninja クラスを拡張 2. deferred の _super を使い Ninja の親クラスを Person に設定 (Ninja に _superClass プロパティを設定する)
  18. 18. つまりは…… • A() 演算子 B() のとき 1. A() 2. B() 3. A の返したオブジェクトの valueOf • という順番で呼ばれてくれれば何でも良い • << である必要性は無い – def(“Ninja”) >> Person({ … }); – def(“Ninja”) + Person({ … });
  19. 19. this._super();
  20. 20. _super(); • 関数の caller プロパティを使って _super の呼び出し元 メソッドを取得. • メソッドの _class プロパティによりクラスを取得 • クラスの _super プロパティにより親クラスを取得 • メソッドの _name プロパティによりメソッドの名前を 取得し, 親クラスの持つ同名メソッドを呼ぶ
  21. 21. _super() の使う各プロパティ • Klass.extend 時に追加 – メソッドの _name – メソッドの _class • deferred.valueOf により追加 – クラスの _super • JavaScript 標準 – arguments.callee • その関数自身 • JavaScript 非標準 (ほぼ全てのブラウザが実装) – caller プロパティ • その関数を呼んだ関数
  22. 22. まとめ
  23. 23. まとめ • def (クラス名) (定義); – 関数を返す関数 • def (クラス名) << 親クラス(定義); – valueOf – << である必要なし • this._super(); – arguments.callee.caller
  24. 24. 演算子オーバーロード欲しい
  25. 25. 資料 • def.js – http://github.com/tobeytailor/def.js • 日本語の解説コメントをつけたコード – https://gist.github.com/2ac889f4b0276ddf9586 ご静聴ありがとうございました

×