defjs をひも解く
Upcoming SlideShare
Loading in...5
×
 

defjs をひも解く

on

  • 3,125 views

 

Statistics

Views

Total Views
3,125
Views on SlideShare
2,644
Embed Views
481

Actions

Likes
1
Downloads
9
Comments
0

4 Embeds 481

http://d.hatena.ne.jp 476
http://webcache.googleusercontent.com 3
http://static.slidesharecdn.com 1
http://hatenatunnel.appspot.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

defjs をひも解く defjs をひも解く Presentation Transcript

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